/* * If we negotiate a 10Mbps mode, we need to check for an alternate * PHY and make sure it's enabled and set correctly. */ void mlphy_status(struct mii_softc *sc) { struct mlphy_softc *msc = (struct mlphy_softc *)sc; struct mii_data *mii = sc->mii_pdata; struct mii_softc *other = NULL; /* See if there's another PHY on the bus with us. */ LIST_FOREACH(other, &mii->mii_phys, mii_list) if (other != sc) break; ukphy_status(sc); if (IFM_SUBTYPE(mii->mii_media_active) != IFM_10_T) { msc->ml_state = ML_STATE_AUTO_SELF; if (other != NULL) { mii_phy_reset(other); PHY_WRITE(other, MII_BMCR, BMCR_ISO); } } if (IFM_SUBTYPE(mii->mii_media_active) == IFM_10_T) { msc->ml_state = ML_STATE_AUTO_OTHER; mlphy_reset(&msc->ml_mii); PHY_WRITE(&msc->ml_mii, MII_BMCR, BMCR_ISO); if (other != NULL) { mii_phy_reset(other); mii_phy_auto(other, 1); } } }
int ieee80211_media2rate(int mword) { #define N(a) (sizeof(a) / sizeof(a[0])) static const int ieeerates[] = { -1, /* IFM_AUTO */ 0, /* IFM_MANUAL */ 0, /* IFM_NONE */ 2, /* IFM_IEEE80211_FH1 */ 4, /* IFM_IEEE80211_FH2 */ 4, /* IFM_IEEE80211_DS2 */ 11, /* IFM_IEEE80211_DS5 */ 22, /* IFM_IEEE80211_DS11 */ 2, /* IFM_IEEE80211_DS1 */ 44, /* IFM_IEEE80211_DS22 */ 12, /* IFM_IEEE80211_OFDM6 */ 18, /* IFM_IEEE80211_OFDM9 */ 24, /* IFM_IEEE80211_OFDM12 */ 36, /* IFM_IEEE80211_OFDM18 */ 48, /* IFM_IEEE80211_OFDM24 */ 72, /* IFM_IEEE80211_OFDM36 */ 96, /* IFM_IEEE80211_OFDM48 */ 108, /* IFM_IEEE80211_OFDM54 */ 144, /* IFM_IEEE80211_OFDM72 */ }; return IFM_SUBTYPE(mword) < N(ieeerates) ? ieeerates[IFM_SUBTYPE(mword)] : 0; #undef N }
static void le_dma_nocarrier(struct lance_softc *sc) { struct le_dma_softc *lesc = (struct le_dma_softc *)sc; /* * Check if the user has requested a certain cable type, and * if so, honor that request. */ if (L64854_GCSR(lesc->sc_dma) & E_TP_AUI) { switch (IFM_SUBTYPE(sc->sc_media.ifm_media)) { case IFM_10_5: case IFM_AUTO: if_printf(sc->sc_ifp, "lost carrier on UTP port, " "switching to AUI port\n"); le_dma_setaui(sc); } } else { switch (IFM_SUBTYPE(sc->sc_media.ifm_media)) { case IFM_10_T: case IFM_AUTO: if_printf(sc->sc_ifp, "lost carrier on AUI port, " "switching to UTP port\n"); le_dma_setutp(sc); } } }
int rtems_ifmedia2str (int media, char *buf, int bufsz) { const char *mdesc; const char *dupdesc = 0; /* only ethernet supported, so far */ if (IFM_ETHER != IFM_TYPE (media)) return -1; if (!(mdesc = find_desc (IFM_SUBTYPE (media), shared_media_strings))) mdesc = find_desc (IFM_SUBTYPE (media), ethern_media_strings); if (!mdesc) return -1; if (IFM_NONE != IFM_SUBTYPE (media)) dupdesc = IFM_FDX & media ? " full-duplex" : " half-duplex"; return WHATPRINT (buf, bufsz, "Ethernet [phy instance: %" PRId32 "]: (link %s, autoneg %s) -- media: %s%s", (int32_t) IFM_INST (media), IFM_LINK_OK & media ? "ok" : "down", IFM_ANEG_DIS & media ? "off" : "on", mdesc, dupdesc ? dupdesc : ""); }
static uint16_t atphy_anar(struct ifmedia_entry *ife) { uint16_t anar = 0; switch (IFM_SUBTYPE(ife->ifm_media)) { case IFM_AUTO: anar |= ANAR_TX_FD | ANAR_TX | ANAR_10_FD | ANAR_10; return anar; case IFM_1000_T: return anar; case IFM_100_TX: anar |= ANAR_TX; break; case IFM_10_T: anar |= ANAR_10; break; default: return 0; } if ((ife->ifm_media & IFM_GMASK) & IFM_FDX) { if (IFM_SUBTYPE(ife->ifm_media) == IFM_100_TX) anar |= ANAR_TX_FD; else anar |= ANAR_10_FD; } return anar; }
/* * Set media options. */ int qe_ifmedia_upd(struct ifnet *ifp) { struct qe_softc *sc = ifp->if_softc; struct ifmedia *ifm = &sc->sc_ifmedia; bus_space_tag_t t = sc->sc_bustag; bus_space_handle_t mr = sc->sc_mr; int newmedia = ifm->ifm_media; uint8_t plscc, phycc; #if defined(SUN4U) || defined(__GNUC__) (void)&t; #endif if (IFM_TYPE(newmedia) != IFM_ETHER) return (EINVAL); plscc = bus_space_read_1(t, mr, QE_MRI_PLSCC) & ~QE_MR_PLSCC_PORTMASK; phycc = bus_space_read_1(t, mr, QE_MRI_PHYCC) & ~QE_MR_PHYCC_ASEL; if (IFM_SUBTYPE(newmedia) == IFM_AUTO) phycc |= QE_MR_PHYCC_ASEL; else if (IFM_SUBTYPE(newmedia) == IFM_10_T) plscc |= QE_MR_PLSCC_TP; else if (IFM_SUBTYPE(newmedia) == IFM_10_5) plscc |= QE_MR_PLSCC_AUI; bus_space_write_1(t, mr, QE_MRI_PLSCC, plscc); bus_space_write_1(t, mr, QE_MRI_PHYCC, phycc); return (0); }
static void lenocarrier(struct lance_softc *sc) { struct le_softc *lesc = (struct le_softc *)sc; /* * Check if the user has requested a certain cable type, and * if so, honor that request. */ printf("%s: lost carrier on ", device_xname(sc->sc_dev)); if (L64854_GCSR(lesc->sc_dma) & E_TP_AUI) { printf("UTP port"); switch (IFM_SUBTYPE(sc->sc_media.ifm_media)) { case IFM_10_5: case IFM_AUTO: printf(", switching to AUI port"); lesetaui(sc); } } else { printf("AUI port"); switch (IFM_SUBTYPE(sc->sc_media.ifm_media)) { case IFM_10_T: case IFM_AUTO: printf(", switching to UTP port"); lesetutp(sc); } } printf("\n"); }
void mii_phy_setmedia(struct mii_softc *sc) { struct mii_data *mii = sc->mii_pdata; struct ifmedia_entry *ife = mii->mii_media.ifm_cur; int bmcr, anar, gtcr; if (IFM_SUBTYPE(ife->ifm_media) == IFM_AUTO) { /* * Force renegotiation if MIIF_DOPAUSE or MIIF_FORCEANEG. * The former is necessary as we might switch from flow- * control advertisment being off to on or vice versa. */ if ((PHY_READ(sc, MII_BMCR) & BMCR_AUTOEN) == 0 || (sc->mii_flags & (MIIF_DOPAUSE | MIIF_FORCEANEG)) != 0) (void)mii_phy_auto(sc); return; } /* * Table index is stored in the media entry. */ KASSERT(ife->ifm_data >=0 && ife->ifm_data < MII_NMEDIA, ("invalid ife->ifm_data (0x%x) in mii_phy_setmedia", ife->ifm_data)); anar = mii_media_table[ife->ifm_data].mm_anar; bmcr = mii_media_table[ife->ifm_data].mm_bmcr; gtcr = mii_media_table[ife->ifm_data].mm_gtcr; if (IFM_SUBTYPE(ife->ifm_media) == IFM_1000_T) { gtcr |= GTCR_MAN_MS; if ((ife->ifm_media & IFM_ETH_MASTER) != 0) gtcr |= GTCR_ADV_MS; } if ((ife->ifm_media & IFM_GMASK) == (IFM_FDX | IFM_FLOW) || (sc->mii_flags & MIIF_FORCEPAUSE) != 0) { if ((sc->mii_flags & MIIF_IS_1000X) != 0) anar |= ANAR_X_PAUSE_TOWARDS; else { 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; } } if ((ife->ifm_media & IFM_LOOP) != 0) bmcr |= BMCR_LOOP; PHY_WRITE(sc, MII_ANAR, anar); PHY_WRITE(sc, MII_BMCR, bmcr); if ((sc->mii_flags & MIIF_HAVE_GTCR) != 0) PHY_WRITE(sc, MII_100T2CR, gtcr); }
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); }
void vte_miibus_statchg(struct device *dev) { struct vte_softc *sc = (struct vte_softc *)dev; struct ifnet *ifp = &sc->sc_arpcom.ac_if; struct mii_data *mii; uint16_t val; if ((ifp->if_flags & IFF_RUNNING) == 0) return; mii = &sc->sc_miibus; sc->vte_flags &= ~VTE_FLAG_LINK; if ((mii->mii_media_status & (IFM_ACTIVE | IFM_AVALID)) == (IFM_ACTIVE | IFM_AVALID)) { switch (IFM_SUBTYPE(mii->mii_media_active)) { case IFM_10_T: case IFM_100_TX: sc->vte_flags |= VTE_FLAG_LINK; break; default: break; } } /* Stop RX/TX MACs. */ vte_stop_mac(sc); /* Program MACs with resolved duplex and flow control. */ if ((sc->vte_flags & VTE_FLAG_LINK) != 0) { /* * Timer waiting time : (63 + TIMER * 64) MII clock. * MII clock : 25MHz(100Mbps) or 2.5MHz(10Mbps). */ if (IFM_SUBTYPE(mii->mii_media_active) == IFM_100_TX) val = 18 << VTE_IM_TIMER_SHIFT; else val = 1 << VTE_IM_TIMER_SHIFT; sc->vte_int_rx_mod = VTE_IM_RX_BUNDLE_DEFAULT; val |= sc->vte_int_rx_mod << VTE_IM_BUNDLE_SHIFT; /* 48.6us for 100Mbps, 50.8us for 10Mbps */ CSR_WRITE_2(sc, VTE_MRICR, val); if (IFM_SUBTYPE(mii->mii_media_active) == IFM_100_TX) val = 18 << VTE_IM_TIMER_SHIFT; else val = 1 << VTE_IM_TIMER_SHIFT; sc->vte_int_tx_mod = VTE_IM_TX_BUNDLE_DEFAULT; val |= sc->vte_int_tx_mod << VTE_IM_BUNDLE_SHIFT; /* 48.6us for 100Mbps, 50.8us for 10Mbps */ CSR_WRITE_2(sc, VTE_MTICR, val); vte_mac_config(sc); vte_start_mac(sc); } }
const char * get_media_subtype_string(uint64_t mword) { const struct ifmedia_description *desc; for (desc = ifm_subtype_descriptions; desc->ifmt_string != NULL; desc++) { if (IFM_TYPE_MATCH(desc->ifmt_word, mword) && IFM_SUBTYPE(desc->ifmt_word) == IFM_SUBTYPE(mword)) return (desc->ifmt_string); } return ("<unknown subtype>"); }
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 void brgphy_setmedia(struct mii_softc *sc, int media) { int bmcr = 0, gig; switch (IFM_SUBTYPE(media)) { case IFM_2500_SX: break; case IFM_1000_SX: case IFM_1000_T: bmcr = BRGPHY_S1000; break; case IFM_100_TX: bmcr = BRGPHY_S100; break; case IFM_10_T: default: bmcr = BRGPHY_S10; break; } if ((media & IFM_FDX) != 0) { bmcr |= BRGPHY_BMCR_FDX; gig = BRGPHY_1000CTL_AFD; } else { gig = BRGPHY_1000CTL_AHD; } /* Force loopback to disconnect PHY from Ethernet medium. */ brgphy_enable_loopback(sc); PHY_WRITE(sc, BRGPHY_MII_1000CTL, 0); PHY_WRITE(sc, BRGPHY_MII_ANAR, BRGPHY_SEL_TYPE); if (IFM_SUBTYPE(media) != IFM_1000_T && IFM_SUBTYPE(media) != IFM_1000_SX) { PHY_WRITE(sc, BRGPHY_MII_BMCR, bmcr); return; } if (IFM_SUBTYPE(media) == IFM_1000_T) { gig |= BRGPHY_1000CTL_MSE; if ((media & IFM_ETH_MASTER) != 0) gig |= BRGPHY_1000CTL_MSC; } PHY_WRITE(sc, BRGPHY_MII_1000CTL, gig); PHY_WRITE(sc, BRGPHY_MII_BMCR, bmcr | BRGPHY_BMCR_AUTOEN | BRGPHY_BMCR_STARTNEG); }
int ieee80211_media2rate(uint64_t mword) { int i; static const struct { uint64_t subtype; int rate; } ieeerates[] = { { IFM_AUTO, -1 }, { IFM_MANUAL, 0 }, { IFM_NONE, 0 }, { IFM_IEEE80211_DS1, 2 }, { IFM_IEEE80211_DS2, 4 }, { IFM_IEEE80211_DS5, 11 }, { IFM_IEEE80211_DS11, 22 }, { IFM_IEEE80211_DS22, 44 }, { IFM_IEEE80211_OFDM6, 12 }, { IFM_IEEE80211_OFDM9, 18 }, { IFM_IEEE80211_OFDM12, 24 }, { IFM_IEEE80211_OFDM18, 36 }, { IFM_IEEE80211_OFDM24, 48 }, { IFM_IEEE80211_OFDM36, 72 }, { IFM_IEEE80211_OFDM48, 96 }, { IFM_IEEE80211_OFDM54, 108 }, { IFM_IEEE80211_OFDM72, 144 }, }; for (i = 0; i < nitems(ieeerates); i++) { if (ieeerates[i].subtype == IFM_SUBTYPE(mword)) return ieeerates[i].rate; } return 0; }
int ieee80211_media2rate(int mword) { #define N(a) (sizeof(a) / sizeof(a[0])) int i; static const struct { int subtype; int rate; } ieeerates[] = { { IFM_AUTO, -1 }, { IFM_MANUAL, 0 }, { IFM_NONE, 0 }, { IFM_IEEE80211_DS1, 2 }, { IFM_IEEE80211_DS2, 4 }, { IFM_IEEE80211_DS5, 11 }, { IFM_IEEE80211_DS11, 22 }, { IFM_IEEE80211_DS22, 44 }, { IFM_IEEE80211_OFDM6, 12 }, { IFM_IEEE80211_OFDM9, 18 }, { IFM_IEEE80211_OFDM12, 24 }, { IFM_IEEE80211_OFDM18, 36 }, { IFM_IEEE80211_OFDM24, 48 }, { IFM_IEEE80211_OFDM36, 72 }, { IFM_IEEE80211_OFDM48, 96 }, { IFM_IEEE80211_OFDM54, 108 }, { IFM_IEEE80211_OFDM72, 144 }, }; for (i = 0; i < N(ieeerates); i++) { if (ieeerates[i].subtype == IFM_SUBTYPE(mword)) return ieeerates[i].rate; } return 0; #undef N }
static int axgbe_media_change(struct ifnet *ifp) { struct axgbe_softc *sc; int cur_media; sc = ifp->if_softc; sx_xlock(&sc->prv.an_mutex); cur_media = sc->media.ifm_cur->ifm_media; switch (IFM_SUBTYPE(cur_media)) { case IFM_10G_KR: sc->prv.phy.speed = SPEED_10000; sc->prv.phy.autoneg = AUTONEG_DISABLE; break; case IFM_2500_KX: sc->prv.phy.speed = SPEED_2500; sc->prv.phy.autoneg = AUTONEG_DISABLE; break; case IFM_1000_KX: sc->prv.phy.speed = SPEED_1000; sc->prv.phy.autoneg = AUTONEG_DISABLE; break; case IFM_AUTO: sc->prv.phy.autoneg = AUTONEG_ENABLE; break; } sx_xunlock(&sc->prv.an_mutex); return (-sc->prv.phy_if.phy_config_aneg(&sc->prv)); }
int lemediachange(struct lance_softc *sc) { struct ifmedia *ifm = &sc->sc_media; if (IFM_TYPE(ifm->ifm_media) != IFM_ETHER) return (EINVAL); /* * Switch to the selected media. If autoselect is * set, we don't really have to do anything. We'll * switch to the other media when we detect loss of * carrier. */ switch (IFM_SUBTYPE(ifm->ifm_media)) { case IFM_10_T: lesetutp(sc); break; case IFM_10_5: lesetaui(sc); break; case IFM_AUTO: break; default: return (EINVAL); } return (0); }
static int tr_pcmcia_mediachange(struct tr_softc *sc) { int setspeed = 0; if (IFM_TYPE(sc->sc_media.ifm_media) != IFM_TOKEN) return EINVAL; switch (IFM_SUBTYPE(sc->sc_media.ifm_media)) { case IFM_TOK_STP16: case IFM_TOK_UTP16: if ((sc->sc_init_status & RSP_16) == 0) setspeed = 1; break; case IFM_TOK_STP4: case IFM_TOK_UTP4: if ((sc->sc_init_status & RSP_16) != 0) setspeed = 1; break; } if (setspeed != 0) { tr_stop(sc); if (sc->sc_enabled) tr_pcmcia_disable(sc); sc->sc_init_status ^= RSP_16; /* XXX 100 Mbit/s */ if (sc->sc_enabled) tr_pcmcia_enable(sc); } /* * XXX Handle Early Token Release !!!! */ return 0; }
void tsec_mii_statchg(struct device *self) { struct tsec_softc *sc = (void *)self; uint32_t maccfg2, ecntrl; ecntrl = tsec_read(sc, TSEC_ECNTRL); maccfg2 = tsec_read(sc, TSEC_MACCFG2); maccfg2 &= ~TSEC_MACCFG2_IF_MODE; switch (IFM_SUBTYPE(sc->sc_mii.mii_media_active)) { case IFM_1000_SX: case IFM_1000_LX: case IFM_1000_CX: case IFM_1000_T: maccfg2 |= TSEC_MACCFG2_IF_GMII; break; case IFM_100_TX: ecntrl |= TSEC_ECNTRL_R100M; maccfg2 |= TSEC_MACCFG2_IF_MII; break; case IFM_10_T: ecntrl &= ~TSEC_ECNTRL_R100M; maccfg2 |= TSEC_MACCFG2_IF_MII; break; } if ((sc->sc_mii.mii_media_active & IFM_GMASK) == IFM_FDX) maccfg2 |= TSEC_MACCFG2_FDX; else maccfg2 &= ~TSEC_MACCFG2_FDX; tsec_write(sc, TSEC_MACCFG2, maccfg2); tsec_write(sc, TSEC_ECNTRL, ecntrl); }
static void ed_rtl_get_media(struct ifnet *ifp, struct ifmediareq *imr) { struct ed_softc *sc; sc = ifp->if_softc; imr->ifm_active = sc->ifmedia.ifm_cur->ifm_media; if (IFM_SUBTYPE(imr->ifm_active) == IFM_AUTO) { ED_LOCK(sc); ed_nic_barrier(sc, ED_P0_CR, 1, BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); ed_nic_outb(sc, ED_P0_CR, sc->cr_proto | ED_CR_PAGE_3 | (ed_nic_inb(sc, ED_P0_CR) & (ED_CR_STA | ED_CR_STP))); ed_nic_barrier(sc, ED_P0_CR, 1, BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); switch (ed_nic_inb(sc, ED_RTL80X9_CONFIG0) & (sc->chip_type == ED_CHIP_TYPE_RTL8029 ? ED_RTL80X9_CF0_BNC : (ED_RTL80X9_CF0_AUI | ED_RTL80X9_CF0_BNC))) { case ED_RTL80X9_CF0_BNC: imr->ifm_active |= IFM_10_2; break; case ED_RTL80X9_CF0_AUI: imr->ifm_active |= IFM_10_5; break; default: imr->ifm_active |= IFM_10_T; break; } ED_UNLOCK(sc); } imr->ifm_status = 0; }
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 kr_link_task(void *arg, int pending) { struct kr_softc *sc; struct mii_data *mii; struct ifnet *ifp; /* int lfdx, mfdx; */ sc = (struct kr_softc *)arg; KR_LOCK(sc); mii = device_get_softc(sc->kr_miibus); ifp = sc->kr_ifp; if (mii == NULL || ifp == NULL || (ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) { KR_UNLOCK(sc); return; } if (mii->mii_media_status & IFM_ACTIVE) { if (IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE) sc->kr_link_status = 1; } else sc->kr_link_status = 0; KR_UNLOCK(sc); }
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 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 lxtphy_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 (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 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. */ lxtphy_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); }
void mii_phy_setmedia(struct mii_softc *sc) { struct mii_data *mii = sc->mii_pdata; struct ifmedia_entry *ife = mii->mii_media.ifm_cur; int bmcr, anar, gtcr; if (IFM_SUBTYPE(ife->ifm_media) == IFM_AUTO) { if ((PHY_READ(sc, MII_BMCR) & BMCR_AUTOEN) == 0 || (sc->mii_flags & MIIF_FORCEANEG)) (void) mii_phy_auto(sc, 1); return; } /* * Table index is stored in the media entry. */ #ifdef DIAGNOSTIC if (ife->ifm_data < 0 || ife->ifm_data >= MII_NMEDIA) panic("mii_phy_setmedia"); #endif anar = mii_media_table[ife->ifm_data].mm_anar; bmcr = mii_media_table[ife->ifm_data].mm_bmcr; gtcr = mii_media_table[ife->ifm_data].mm_gtcr; if (mii->mii_media.ifm_media & IFM_ETH_MASTER) { switch (IFM_SUBTYPE(ife->ifm_media)) { case IFM_1000_T: gtcr |= GTCR_MAN_MS|GTCR_ADV_MS; break; default: panic("mii_phy_setmedia: MASTER on wrong media"); } } if (ife->ifm_media & IFM_LOOP) bmcr |= BMCR_LOOP; PHY_WRITE(sc, MII_ANAR, anar); PHY_WRITE(sc, MII_BMCR, bmcr); if (sc->mii_flags & MIIF_HAVE_GTCR) PHY_WRITE(sc, MII_100T2CR, gtcr); }
static int le_pci_mediachange(struct lance_softc *sc) { struct ifmedia *ifm = &sc->sc_media; uint16_t reg; if (IFM_TYPE(ifm->ifm_media) != IFM_ETHER) return (EINVAL); if (IFM_SUBTYPE(ifm->ifm_media) == IFM_HPNA_1) le_pci_wrbcr(sc, LE_BCR49, (le_pci_rdbcr(sc, LE_BCR49) & ~LE_B49_PHYSEL) | 0x1); else if (IFM_SUBTYPE(ifm->ifm_media) == IFM_AUTO) le_pci_wrbcr(sc, LE_BCR2, le_pci_rdbcr(sc, LE_BCR2) | LE_B2_ASEL); else { le_pci_wrbcr(sc, LE_BCR2, le_pci_rdbcr(sc, LE_BCR2) & ~LE_B2_ASEL); reg = le_pci_rdcsr(sc, LE_CSR15); reg &= ~LE_C15_PORTSEL(LE_PORTSEL_MASK); if (IFM_SUBTYPE(ifm->ifm_media) == IFM_10_T) reg |= LE_C15_PORTSEL(LE_PORTSEL_10T); else reg |= LE_C15_PORTSEL(LE_PORTSEL_AUI); le_pci_wrcsr(sc, LE_CSR15, reg); } reg = le_pci_rdbcr(sc, LE_BCR9); if (IFM_OPTIONS(ifm->ifm_media) & IFM_FDX) { reg |= LE_B9_FDEN; /* * Allow FDX on AUI only if explicitly chosen, * not in autoselect mode. */ if (IFM_SUBTYPE(ifm->ifm_media) == IFM_10_5) reg |= LE_B9_AUIFD; else reg &= ~LE_B9_AUIFD; } else reg &= ~LE_B9_FDEN; le_pci_wrbcr(sc, LE_BCR9, reg); return (0); }
static int jmphy_setmedia(struct mii_softc *sc, struct ifmedia_entry *ife) { uint16_t anar, bmcr, gig; gig = 0; bmcr = PHY_READ(sc, MII_BMCR); switch (IFM_SUBTYPE(ife->ifm_media)) { case IFM_AUTO: gig |= GTCR_ADV_1000TFDX | GTCR_ADV_1000THDX; break; case IFM_1000_T: gig |= GTCR_ADV_1000TFDX | GTCR_ADV_1000THDX; break; case IFM_100_TX: case IFM_10_T: break; case IFM_NONE: PHY_WRITE(sc, MII_BMCR, bmcr | BMCR_ISO | BMCR_PDOWN); return (EJUSTRETURN); default: return (EINVAL); } anar = jmphy_anar(ife); if ((IFM_SUBTYPE(ife->ifm_media) == IFM_AUTO || (ife->ifm_media & IFM_FDX) != 0) && ((ife->ifm_media & IFM_FLOW) != 0 || (sc->mii_flags & MIIF_FORCEPAUSE) != 0)) anar |= ANAR_PAUSE_TOWARDS; if ((sc->mii_flags & MIIF_HAVE_GTCR) != 0) { if (IFM_SUBTYPE(ife->ifm_media) == IFM_1000_T) { gig |= GTCR_MAN_MS; if ((ife->ifm_media & IFM_ETH_MASTER) != 0) gig |= GTCR_ADV_MS; } PHY_WRITE(sc, MII_100T2CR, gig); } PHY_WRITE(sc, MII_ANAR, anar | ANAR_CSMA); PHY_WRITE(sc, MII_BMCR, bmcr | BMCR_AUTOEN | BMCR_STARTNEG); return (EJUSTRETURN); }
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); }