static int mlphy_probe(device_t dev) { struct mii_attach_args *ma; device_t parent; ma = device_get_ivars(dev); parent = device_get_parent(device_get_parent(dev)); /* * Micro Linear PHY reports oui == 0 model == 0 */ if (MII_OUI(ma->mii_id1, ma->mii_id2) != 0 || MII_MODEL(ma->mii_id2) != 0) return (ENXIO); /* * Make sure the parent is a `tl'. So far, I have only * encountered the 6692 on an Olicom card with a ThunderLAN * controller chip. */ if (strcmp(device_get_name(parent), "tl") != 0) return (ENXIO); device_set_desc(dev, "Micro Linear 6692 media interface"); return (0); }
int rlphymatch(struct device *parent, void *match, void *aux) { struct mii_attach_args *ma = aux; char *devname; devname = parent->dv_cfdata->cf_driver->cd_name; if (mii_phy_match(ma, rlphys) != NULL) return (10); if (MII_OUI(ma->mii_id1, ma->mii_id2) != 0 || MII_MODEL(ma->mii_id2) != 0) return (0); if ((strcmp(devname, "re") != 0) && (strcmp(devname, "rl") != 0)) return (0); /* * A "real" phy should get preference, but on the 8139 there * is no phyid register. */ return (5); }
void ukphyattach(struct device *parent, struct device *self, void *aux) { struct mii_softc *sc = (struct mii_softc *)self; struct mii_attach_args *ma = aux; struct mii_data *mii = ma->mii_data; printf(": Generic IEEE 802.3u media interface, rev. %d:", MII_REV(ma->mii_id2)); printf(" OUI 0x%06x, model 0x%04x\n", MII_OUI(ma->mii_id1, ma->mii_id2), MII_MODEL(ma->mii_id2)); sc->mii_inst = mii->mii_instance; sc->mii_phy = ma->mii_phyno; sc->mii_funcs = &ukphy_funcs; sc->mii_pdata = mii; sc->mii_flags = ma->mii_flags; /* * Don't do loopback on unknown PHYs. It might confuse some of them. */ sc->mii_flags |= MIIF_NOLOOP; PHY_RESET(sc); sc->mii_capabilities = PHY_READ(sc, MII_BMSR) & ma->mii_capmask; if (sc->mii_capabilities & BMSR_EXTSTAT) sc->mii_extcapabilities = PHY_READ(sc, MII_EXTSR); if ((sc->mii_capabilities & BMSR_MEDIAMASK) == 0 && (sc->mii_extcapabilities & EXTSR_MEDIAMASK) == 0) printf("%s: no media present\n", sc->mii_dev.dv_xname); else mii_phy_add_media(sc); }
static int ruephy_probe(device_t dev) { struct mii_attach_args *ma; device_t parent; ma = device_get_ivars(dev); parent = device_get_parent(device_get_parent(dev)); /* * RealTek RTL8150 PHY doesn't have vendor/device ID registers: * the rue driver fakes up a return value of all zeros. */ if (MII_OUI(ma->mii_id1, ma->mii_id2) != 0 || MII_MODEL(ma->mii_id2) != 0) return (ENXIO); /* * Make sure the parent is an 'rue'. */ if (strcmp(device_get_name(parent), "rue") != 0) return (ENXIO); device_set_desc(dev, "RealTek RTL8150 internal media interface"); return (0); }
int rlphymatch(device_t parent, cfdata_t match, void *aux) { struct mii_attach_args *ma = aux; struct mii_data *mii = ma->mii_data; if (mii->mii_instance != 0) return 0; if (mii_phy_match(ma, rlphys) != NULL) return (10); if (MII_OUI(ma->mii_id1, ma->mii_id2) != 0 || MII_MODEL(ma->mii_id2) != 0) return 0; if (!device_is_a(parent, "rtk") && !device_is_a(parent, "re")) return 0; /* * A "real" phy should get preference, but on the 8139 there * is no phyid register. */ return 5; }
int exphymatch(struct device *parent, void *match, void *aux) { struct mii_attach_args *ma = aux; /* * Since 3com's PHY for some xl adapters is braindead and doesn't * report the proper OUI/MODEL information, we have this stupid * match function. */ if ((strcmp(parent->dv_cfdata->cf_driver->cd_name, "xl") == 0) && ((MII_OUI(ma->mii_id1, ma->mii_id2) == 0 && MII_MODEL(ma->mii_id2) == 0) || (MII_OUI(ma->mii_id1, ma->mii_id2) == MII_OUI_3COM && MII_MODEL(ma->mii_id2) == 0))) return (10); return (0); }
const struct mii_phydesc * mii_phy_match(const struct mii_attach_args *ma, const struct mii_phydesc *mpd) { for (; mpd->mpd_name != NULL; mpd++) { if (MII_OUI(ma->mii_id1, ma->mii_id2) == mpd->mpd_oui && MII_MODEL(ma->mii_id2) == mpd->mpd_model) return (mpd); } return (NULL); }
static int tdkphy_probe(device_t dev) { struct mii_attach_args *ma; ma = device_get_ivars(dev); if ((MII_OUI(ma->mii_id1, ma->mii_id2) != MII_OUI_TDK || MII_MODEL(ma->mii_id2) != MII_MODEL_TDK_78Q2120)) return (ENXIO); device_set_desc(dev, MII_STR_TDK_78Q2120); return (0); }
int mii_print(void *aux, const char *pnp) { struct mii_attach_args *ma = aux; if (pnp != NULL) printf("OUI 0x%06x model 0x%04x rev %d at %s", MII_OUI(ma->mii_id1, ma->mii_id2), MII_MODEL(ma->mii_id2), MII_REV(ma->mii_id2), pnp); printf(" phy %d", ma->mii_phyno); return (UNCONF); }
const struct mii_phydesc * mii_phy_match_gen(const struct mii_attach_args *ma, const struct mii_phydesc *mpd, size_t len) { for (; mpd->mpd_name != NULL; mpd = (const struct mii_phydesc *)((const char *)mpd + len)) { if (MII_OUI(ma->mii_id1, ma->mii_id2) == mpd->mpd_oui && MII_MODEL(ma->mii_id2) == mpd->mpd_model) return (mpd); } return (NULL); }
static void gentbiattach(device_t parent, device_t self, void *aux) { struct mii_softc *sc = device_private(self); struct mii_attach_args *ma = aux; struct mii_data *mii = ma->mii_data; int oui = MII_OUI(ma->mii_id1, ma->mii_id2); int model = MII_MODEL(ma->mii_id2); int rev = MII_REV(ma->mii_id2); const char *descr; if ((descr = mii_get_descr(oui, model)) != NULL) aprint_normal(": %s (OUI 0x%06x, model 0x%04x), rev. %d\n", descr, oui, model, rev); else aprint_normal(": OUI 0x%06x, model 0x%04x, rev. %d\n", oui, model, rev); aprint_naive(": Generic ten-bit interface\n"); sc->mii_dev = self; sc->mii_inst = mii->mii_instance; sc->mii_phy = ma->mii_phyno; sc->mii_mpd_oui = oui; sc->mii_mpd_model = model; sc->mii_mpd_rev = rev; sc->mii_funcs = &gentbi_funcs; sc->mii_pdata = mii; sc->mii_flags = ma->mii_flags; sc->mii_anegticks = MII_ANEGTICKS; PHY_RESET(sc); /* * Mask out all media in the BMSR. We only are really interested * in "auto". */ sc->mii_capabilities = PHY_READ(sc, MII_BMSR) & ma->mii_capmask & ~BMSR_MEDIAMASK; if (sc->mii_capabilities & BMSR_EXTSTAT) sc->mii_extcapabilities = PHY_READ(sc, MII_EXTSR); aprint_normal_dev(self, ""); if ((sc->mii_capabilities & BMSR_MEDIAMASK) == 0 && (sc->mii_extcapabilities & EXTSR_MEDIAMASK) == 0) aprint_error("no media present"); else mii_phy_add_media(sc); aprint_normal("\n"); }
int ukphy_attach(device_t dev) { struct mii_softc *sc; struct mii_attach_args *ma; struct mii_data *mii; sc = device_get_softc(dev); ma = device_get_ivars(dev); mii_softc_init(sc, ma); sc->mii_dev = device_get_parent(dev); mii = device_get_softc(sc->mii_dev); LIST_INSERT_HEAD(&mii->mii_phys, sc, mii_list); if (bootverbose) { device_printf(dev, "OUI 0x%06x, model 0x%04x, rev. %d\n", MII_OUI(ma->mii_id1, ma->mii_id2), MII_MODEL(ma->mii_id2), MII_REV(ma->mii_id2)); } sc->mii_inst = mii->mii_instance; sc->mii_service = ukphy_service; sc->mii_pdata = mii; mii->mii_instance++; /* * Don't do loopback on unknown PHYs. It might confuse some of them. */ sc->mii_flags |= MIIF_NOLOOP; mii_phy_reset(sc); sc->mii_capabilities = PHY_READ(sc, MII_BMSR) & ma->mii_capmask; if (sc->mii_capabilities & BMSR_EXTSTAT) sc->mii_extcapabilities = PHY_READ(sc, MII_EXTSR); device_printf(dev, " "); if ((sc->mii_capabilities & BMSR_MEDIAMASK) == 0 && (sc->mii_extcapabilities & EXTSR_MEDIAMASK) == 0) kprintf("no media present"); else mii_phy_add_media(sc); kprintf("\n"); MIIBUS_MEDIAINIT(sc->mii_dev); return(0); }
int dcphy_match(struct device *parent, void *match, void *aux) { struct mii_attach_args *ma = aux; /* * The dc driver will report the 21143 vendor and device * ID to let us know that it wants us to attach. */ if (MII_OUI(ma->mii_id1, ma->mii_id2) == MII_OUI_xxDEC && MII_MODEL(ma->mii_id2) == MII_MODEL_xxDEC_xxDC) return (10); return (0); }
static int tdkphy_attach(device_t dev) { struct mii_softc *sc; struct mii_attach_args *ma; struct mii_data *mii; sc = device_get_softc(dev); ma = device_get_ivars(dev); sc->mii_dev = device_get_parent(dev); mii = device_get_softc(sc->mii_dev); LIST_INSERT_HEAD(&mii->mii_phys, sc, mii_list); if (bootverbose) device_printf(dev, "OUI 0x%06x, model 0x%04x, rev. %d\n", MII_OUI(ma->mii_id1, ma->mii_id2), MII_MODEL(ma->mii_id2), MII_REV(ma->mii_id2)); sc->mii_inst = mii->mii_instance; sc->mii_phy = ma->mii_phyno; sc->mii_service = tdkphy_service; sc->mii_pdata = mii; mii->mii_instance++; sc->mii_flags |= MIIF_NOISOLATE; #define ADD(m, c) ifmedia_add(&mii->mii_media, (m), (c), NULL) ADD(IFM_MAKEWORD(IFM_ETHER, IFM_NONE, 0, sc->mii_inst), BMCR_ISO); #if 0 ADD(IFM_MAKEWORD(IFM_ETHER, IFM_100_TX, IFM_LOOP, sc->mii_inst), BMCR_LOOP|BMCR_S100); #endif mii_phy_reset(sc); sc->mii_capabilities = PHY_READ(sc, MII_BMSR) & ma->mii_capmask; device_printf(dev, " "); mii_add_media(mii, sc->mii_capabilities, sc->mii_inst); printf("\n"); #undef ADD MIIBUS_MEDIAINIT(sc->mii_dev); return(0); }
void mii_phy_dev_attach(device_t dev, u_int flags, const struct mii_phy_funcs *mpf, int add_media) { struct mii_softc *sc; struct mii_attach_args *ma; struct mii_data *mii; sc = device_get_softc(dev); ma = device_get_ivars(dev); sc->mii_dev = device_get_parent(dev); mii = ma->mii_data; LIST_INSERT_HEAD(&mii->mii_phys, sc, mii_list); sc->mii_flags = flags | miibus_get_flags(dev); sc->mii_mpd_oui = MII_OUI(ma->mii_id1, ma->mii_id2); sc->mii_mpd_model = MII_MODEL(ma->mii_id2); sc->mii_mpd_rev = MII_REV(ma->mii_id2); sc->mii_capmask = ma->mii_capmask; sc->mii_inst = mii->mii_instance++; sc->mii_phy = ma->mii_phyno; sc->mii_offset = ma->mii_offset; sc->mii_funcs = mpf; sc->mii_pdata = mii; if (bootverbose) device_printf(dev, "OUI 0x%06x, model 0x%04x, rev. %d\n", sc->mii_mpd_oui, sc->mii_mpd_model, sc->mii_mpd_rev); if (add_media == 0) return; PHY_RESET(sc); sc->mii_capabilities = PHY_READ(sc, MII_BMSR) & sc->mii_capmask; if (sc->mii_capabilities & BMSR_EXTSTAT) sc->mii_extcapabilities = PHY_READ(sc, MII_EXTSR); device_printf(dev, " "); mii_phy_add_media(sc); printf("\n"); MIIBUS_MEDIAINIT(sc->mii_dev); }
static int atphy_attach(device_t dev) { struct atphy_softc *asc; struct mii_softc *sc; struct mii_attach_args *ma; struct mii_data *mii; asc = device_get_softc(dev); sc = &asc->mii_sc; ma = device_get_ivars(dev); sc->mii_dev = device_get_parent(dev); mii = device_get_softc(sc->mii_dev); LIST_INSERT_HEAD(&mii->mii_phys, sc, mii_list); sc->mii_inst = mii->mii_instance; sc->mii_phy = ma->mii_phyno; sc->mii_service = atphy_service; sc->mii_pdata = mii; sc->mii_anegticks = MII_ANEGTICKS_GIGE; mii->mii_instance++; asc->mii_oui = MII_OUI(ma->mii_id1, ma->mii_id2); asc->mii_model = MII_MODEL(ma->mii_id2); asc->mii_rev = MII_REV(ma->mii_id2); if (bootverbose) device_printf(dev, "OUI 0x%06x, model 0x%04x, rev. %d\n", asc->mii_oui, asc->mii_model, asc->mii_rev); atphy_reset(sc); sc->mii_capabilities = PHY_READ(sc, MII_BMSR) & ma->mii_capmask; if (sc->mii_capabilities & BMSR_EXTSTAT) sc->mii_extcapabilities = PHY_READ(sc, MII_EXTSR); device_printf(dev, " "); mii_phy_add_media(sc); printf("\n"); MIIBUS_MEDIAINIT(sc->mii_dev); return(0); }
static int urlphy_match(device_t parent, cfdata_t match, void *aux) { struct mii_attach_args *ma = aux; /* * RTL8150 reports OUI == 0, MODEL == 0 */ if (MII_OUI(ma->mii_id1, ma->mii_id2) != 0 && MII_MODEL(ma->mii_id2) != 0) return (0); /* * Make sure the parent is an 'url' device. */ if (!device_is_a(parent, "url")) return(0); return (10); }
int urlphy_match(struct device *parent, void *match, void *aux) { struct mii_attach_args *ma = aux; /* * RTL8150 reports OUT == 0, MODEL == 0 */ if (MII_OUI(ma->mii_id1, ma->mii_id2) != 0 && MII_MODEL(ma->mii_id2) != 0) return (0); /* * Make sure the parent is an 'url' device. */ if (strcmp(parent->dv_cfdata->cf_driver->cd_name, "url") != 0) return (0); return (10); }
int mlphy_probe(struct device *parent, void *match, void *aux) { struct mii_attach_args *ma = aux; /* * Micro Linear PHY reports oui == 0 model == 0 */ if (MII_OUI(ma->mii_id1, ma->mii_id2) != 0 || MII_MODEL(ma->mii_id2) != 0) return (0); /* * Make sure the parent is a `tl'. So far, I have only * encountered the 6692 on an Olicom card with a ThunderLAN * controller chip. */ if (strcmp(parent->dv_cfdata->cf_driver->cd_name, "tl") != 0) return (0); return (10); }
static int tdkphy_attach(device_t dev) { struct mii_softc *sc; struct mii_attach_args *ma; struct mii_data *mii; sc = device_get_softc(dev); ma = device_get_ivars(dev); sc->mii_dev = device_get_parent(dev); mii = device_get_softc(sc->mii_dev); LIST_INSERT_HEAD(&mii->mii_phys, sc, mii_list); if (bootverbose) device_printf(dev, "OUI 0x%06x, model 0x%04x, rev. %d\n", MII_OUI(ma->mii_id1, ma->mii_id2), MII_MODEL(ma->mii_id2), MII_REV(ma->mii_id2)); sc->mii_inst = mii->mii_instance; sc->mii_phy = ma->mii_phyno; sc->mii_service = tdkphy_service; sc->mii_pdata = mii; mii->mii_instance++; /* * Apparently, we can't do loopback on this PHY. */ sc->mii_flags |= MIIF_NOLOOP; mii_phy_reset(sc); sc->mii_capabilities = PHY_READ(sc, MII_BMSR) & ma->mii_capmask; device_printf(dev, " "); mii_phy_add_media(sc); printf("\n"); MIIBUS_MEDIAINIT(sc->mii_dev); return (0); }
void atphy_attach(device_t parent, device_t self, void *aux) { struct mii_softc *sc = device_private(self); struct mii_attach_args *ma = aux; struct mii_data *mii = ma->mii_data; const struct mii_phydesc *mpd; uint16_t bmsr; mpd = mii_phy_match(ma, etphys); aprint_naive(": Media interface\n"); aprint_normal(": %s, rev. %d\n", mpd->mpd_name, MII_REV(ma->mii_id2)); sc->mii_dev = self; sc->mii_inst = mii->mii_instance; sc->mii_phy = ma->mii_phyno; sc->mii_mpd_oui = MII_OUI(ma->mii_id1, ma->mii_id2); sc->mii_mpd_model = MII_MODEL(ma->mii_id2); sc->mii_mpd_rev = MII_REV(ma->mii_id2); sc->mii_funcs = &atphy_funcs; sc->mii_pdata = mii; sc->mii_flags = ma->mii_flags; if (atphy_is_gige(mpd)) sc->mii_anegticks = MII_ANEGTICKS_GIGE; else sc->mii_anegticks = MII_ANEGTICKS; sc->mii_flags |= MIIF_NOLOOP; PHY_RESET(sc); bmsr = PHY_READ(sc, MII_BMSR) | PHY_READ(sc, MII_BMSR); sc->mii_capabilities = bmsr & ma->mii_capmask; if (atphy_is_gige(mpd) && (sc->mii_capabilities & BMSR_EXTSTAT)) sc->mii_extcapabilities = PHY_READ(sc, MII_EXTSR); aprint_normal_dev(self, ""); mii_phy_add_media(sc); aprint_normal("\n"); }
static int bmtphy_probe(device_t dev) { struct mii_attach_args *ma; int rval; ma = device_get_ivars(dev); rval = BUS_PROBE_DEFAULT; if (MII_OUI(ma->mii_id1, ma->mii_id2) != MII_OUI_BROADCOM) return (ENXIO); switch (MII_MODEL(ma->mii_id2)) { case MII_MODEL_BROADCOM_3C905B: device_set_desc(dev, MII_STR_BROADCOM_3C905B); rval = BUS_PROBE_LOW_PRIORITY; /* Let exphy take precedence. */ break; case MII_MODEL_BROADCOM_3C905C: device_set_desc(dev, MII_STR_BROADCOM_3C905C); rval = BUS_PROBE_LOW_PRIORITY; /* Let exphy take precedence. */ break; case MII_MODEL_BROADCOM_BCM5201: device_set_desc(dev, MII_STR_BROADCOM_BCM5201); break; case MII_MODEL_BROADCOM_BCM5221: device_set_desc(dev, MII_STR_BROADCOM_BCM5221); break; case MII_MODEL_BROADCOM_BCM4401: device_set_desc(dev, MII_STR_BROADCOM_BCM4401); break; default: return (ENXIO); } return (rval); }
void brgphy_attach(struct device *parent, struct device *self, void *aux) { struct mii_softc *sc = (struct mii_softc *)self; struct bge_softc *bge_sc = NULL; struct bnx_softc *bnx_sc = NULL; struct mii_attach_args *ma = aux; struct mii_data *mii = ma->mii_data; const struct mii_phydesc *mpd; char *devname; int fast_ether = 0; devname = sc->mii_dev.dv_parent->dv_cfdata->cf_driver->cd_name; if (strcmp(devname, "bge") == 0) { bge_sc = mii->mii_ifp->if_softc; if (bge_sc->bge_flags & BGE_10_100_ONLY) fast_ether = 1; } else if (strcmp(devname, "bnx") == 0) bnx_sc = mii->mii_ifp->if_softc; mpd = mii_phy_match(ma, brgphys); printf(": %s, rev. %d\n", mpd->mpd_name, MII_REV(ma->mii_id2)); sc->mii_inst = mii->mii_instance; sc->mii_phy = ma->mii_phyno; sc->mii_oui = MII_OUI(ma->mii_id1, ma->mii_id2); sc->mii_model = MII_MODEL(ma->mii_id2); sc->mii_rev = MII_REV(ma->mii_id2); sc->mii_pdata = mii; sc->mii_flags = ma->mii_flags; if (sc->mii_flags & MIIF_HAVEFIBER) { if (strcmp(devname, "bnx") == 0) { if (BNX_CHIP_NUM(bnx_sc) == BNX_CHIP_NUM_5708) sc->mii_funcs = &brgphy_5708s_funcs; else if (BNX_CHIP_NUM(bnx_sc) == BNX_CHIP_NUM_5709) sc->mii_funcs = &brgphy_5709s_funcs; else sc->mii_funcs = &brgphy_fiber_funcs; } else sc->mii_funcs = &brgphy_fiber_funcs; } else sc->mii_funcs = &brgphy_copper_funcs; if (fast_ether == 1) sc->mii_anegticks = MII_ANEGTICKS; else sc->mii_anegticks = MII_ANEGTICKS_GIGE; sc->mii_flags |= MIIF_NOISOLATE | MIIF_NOLOOP; PHY_RESET(sc); sc->mii_capabilities = PHY_READ(sc, MII_BMSR) & ma->mii_capmask; if (sc->mii_capabilities & BMSR_EXTSTAT) sc->mii_extcapabilities = PHY_READ(sc, MII_EXTSR); #define ADD(m, c) ifmedia_add(&mii->mii_media, (m), (c), NULL) /* Create an instance of Ethernet media. */ ADD(IFM_MAKEWORD(IFM_ETHER, IFM_NONE, 0, sc->mii_inst), BMCR_ISO); /* Add the supported media types */ if (sc->mii_flags & MIIF_HAVEFIBER) { ADD(IFM_MAKEWORD(IFM_ETHER, IFM_1000_SX, IFM_FDX, sc->mii_inst), BRGPHY_S1000 | BRGPHY_BMCR_FDX); /* * 2.5Gb support is a software enabled feature on the * BCM5708S and BCM5709S controllers. */ if (strcmp(devname, "bnx") == 0) { if (bnx_sc->bnx_phy_flags & BNX_PHY_2_5G_CAPABLE_FLAG) ADD(IFM_MAKEWORD(IFM_ETHER, IFM_2500_SX, IFM_FDX, sc->mii_inst), 0); } } else { ADD(IFM_MAKEWORD(IFM_ETHER, IFM_10_T, 0, sc->mii_inst), BRGPHY_S10); ADD(IFM_MAKEWORD(IFM_ETHER, IFM_10_T, IFM_FDX, sc->mii_inst), BRGPHY_S10 | BRGPHY_BMCR_FDX); ADD(IFM_MAKEWORD(IFM_ETHER, IFM_100_TX, 0, sc->mii_inst), BRGPHY_S100); ADD(IFM_MAKEWORD(IFM_ETHER, IFM_100_TX, IFM_FDX, sc->mii_inst), BRGPHY_S100 | BRGPHY_BMCR_FDX); if (fast_ether == 0) { ADD(IFM_MAKEWORD(IFM_ETHER, IFM_1000_T, 0, sc->mii_inst), BRGPHY_S1000); ADD(IFM_MAKEWORD(IFM_ETHER, IFM_1000_T, IFM_FDX, sc->mii_inst), BRGPHY_S1000 | BRGPHY_BMCR_FDX); } } ADD(IFM_MAKEWORD(IFM_ETHER, IFM_AUTO, 0, sc->mii_inst), 0); #undef ADD }
/* Attach the PHY to the MII bus */ static int brgphy_attach(device_t dev) { struct brgphy_softc *bsc; struct bge_softc *bge_sc = NULL; struct bce_softc *bce_sc = NULL; struct mii_softc *sc; struct mii_attach_args *ma; struct mii_data *mii; struct ifnet *ifp; int fast_ether; bsc = device_get_softc(dev); sc = &bsc->mii_sc; ma = device_get_ivars(dev); sc->mii_dev = device_get_parent(dev); mii = device_get_softc(sc->mii_dev); LIST_INSERT_HEAD(&mii->mii_phys, sc, mii_list); /* Initialize mii_softc structure */ sc->mii_inst = mii->mii_instance; sc->mii_phy = ma->mii_phyno; sc->mii_service = brgphy_service; sc->mii_pdata = mii; sc->mii_anegticks = MII_ANEGTICKS_GIGE; sc->mii_flags |= MIIF_NOISOLATE | MIIF_NOLOOP; mii->mii_instance++; /* Initialize brgphy_softc structure */ bsc->mii_oui = MII_OUI(ma->mii_id1, ma->mii_id2); bsc->mii_model = MII_MODEL(ma->mii_id2); bsc->mii_rev = MII_REV(ma->mii_id2); bsc->serdes_flags = 0; fast_ether = 0; if (bootverbose) device_printf(dev, "OUI 0x%06x, model 0x%04x, rev. %d\n", bsc->mii_oui, bsc->mii_model, bsc->mii_rev); /* Handle any special cases based on the PHY ID */ switch (bsc->mii_oui) { case MII_OUI_BROADCOM: case MII_OUI_BROADCOM2: break; case MII_OUI_xxBROADCOM: switch (bsc->mii_model) { case MII_MODEL_xxBROADCOM_BCM5706: /* * The 5464 PHY used in the 5706 supports both copper * and fiber interfaces over GMII. Need to check the * shadow registers to see which mode is actually * in effect, and therefore whether we have 5706C or * 5706S. */ PHY_WRITE(sc, BRGPHY_MII_SHADOW_1C, BRGPHY_SHADOW_1C_MODE_CTRL); if (PHY_READ(sc, BRGPHY_MII_SHADOW_1C) & BRGPHY_SHADOW_1C_ENA_1000X) { bsc->serdes_flags |= BRGPHY_5706S; sc->mii_flags |= MIIF_HAVEFIBER; } break; } break; case MII_OUI_xxBROADCOM_ALT1: switch (bsc->mii_model) { case MII_MODEL_xxBROADCOM_ALT1_BCM5708S: bsc->serdes_flags |= BRGPHY_5708S; sc->mii_flags |= MIIF_HAVEFIBER; break; } break; default: device_printf(dev, "Unrecognized OUI for PHY!\n"); } ifp = sc->mii_pdata->mii_ifp; /* Find the MAC driver associated with this PHY. */ if (strcmp(ifp->if_dname, "bge") == 0) { bge_sc = ifp->if_softc; } else if (strcmp(ifp->if_dname, "bce") == 0) { bce_sc = ifp->if_softc; } /* Todo: Need to add additional controllers such as 5906 & 5787F */ /* The 590x chips are 10/100 only. */ if (bge_sc && pci_get_vendor(bge_sc->bge_dev) == BCOM_VENDORID && (pci_get_device(bge_sc->bge_dev) == BCOM_DEVICEID_BCM5901 || pci_get_device(bge_sc->bge_dev) == BCOM_DEVICEID_BCM5901A2 || pci_get_device(bge_sc->bge_dev) == BCOM_DEVICEID_BCM5906 || pci_get_device(bge_sc->bge_dev) == BCOM_DEVICEID_BCM5906M)) { fast_ether = 1; sc->mii_anegticks = MII_ANEGTICKS; } brgphy_reset(sc); /* Read the PHY's capabilities. */ sc->mii_capabilities = PHY_READ(sc, MII_BMSR) & ma->mii_capmask; if (sc->mii_capabilities & BMSR_EXTSTAT) sc->mii_extcapabilities = PHY_READ(sc, MII_EXTSR); device_printf(dev, " "); #define ADD(m, c) ifmedia_add(&mii->mii_media, (m), (c), NULL) /* Create an instance of Ethernet media. */ ADD(IFM_MAKEWORD(IFM_ETHER, IFM_NONE, 0, sc->mii_inst), BMCR_ISO); /* Add the supported media types */ if ((sc->mii_flags & MIIF_HAVEFIBER) == 0) { ADD(IFM_MAKEWORD(IFM_ETHER, IFM_10_T, 0, sc->mii_inst), BRGPHY_S10); printf("10baseT, "); ADD(IFM_MAKEWORD(IFM_ETHER, IFM_10_T, IFM_FDX, sc->mii_inst), BRGPHY_S10 | BRGPHY_BMCR_FDX); printf("10baseT-FDX, "); ADD(IFM_MAKEWORD(IFM_ETHER, IFM_100_TX, 0, sc->mii_inst), BRGPHY_S100); printf("100baseTX, "); ADD(IFM_MAKEWORD(IFM_ETHER, IFM_100_TX, IFM_FDX, sc->mii_inst), BRGPHY_S100 | BRGPHY_BMCR_FDX); printf("100baseTX-FDX, "); if (fast_ether == 0) { ADD(IFM_MAKEWORD(IFM_ETHER, IFM_1000_T, 0, sc->mii_inst), BRGPHY_S1000); printf("1000baseT, "); ADD(IFM_MAKEWORD(IFM_ETHER, IFM_1000_T, IFM_FDX, sc->mii_inst), BRGPHY_S1000 | BRGPHY_BMCR_FDX); printf("1000baseT-FDX, "); } } else { ADD(IFM_MAKEWORD(IFM_ETHER, IFM_1000_SX, IFM_FDX, sc->mii_inst), BRGPHY_S1000 | BRGPHY_BMCR_FDX); printf("1000baseSX-FDX, "); /* 2.5G support is a software enabled feature on the 5708S and 5709S. */ if (bce_sc && (bce_sc->bce_phy_flags & BCE_PHY_2_5G_CAPABLE_FLAG)) { ADD(IFM_MAKEWORD(IFM_ETHER, IFM_2500_SX, IFM_FDX, sc->mii_inst), 0); printf("2500baseSX-FDX, "); } } ADD(IFM_MAKEWORD(IFM_ETHER, IFM_AUTO, 0, sc->mii_inst), 0); printf("auto\n"); #undef ADD MIIBUS_MEDIAINIT(sc->mii_dev); return (0); }
static void brgphyattach(device_t parent, device_t self, void *aux) { struct brgphy_softc *bsc = device_private(self); struct mii_softc *sc = &bsc->sc_mii; struct mii_attach_args *ma = aux; struct mii_data *mii = ma->mii_data; const struct mii_phydesc *mpd; prop_dictionary_t dict; mpd = mii_phy_match(ma, brgphys); aprint_naive(": Media interface\n"); aprint_normal(": %s, rev. %d\n", mpd->mpd_name, MII_REV(ma->mii_id2)); sc->mii_dev = self; sc->mii_inst = mii->mii_instance; sc->mii_phy = ma->mii_phyno; sc->mii_mpd_oui = MII_OUI(ma->mii_id1, ma->mii_id2); sc->mii_mpd_model = MII_MODEL(ma->mii_id2); sc->mii_mpd_rev = MII_REV(ma->mii_id2); sc->mii_pdata = mii; sc->mii_flags = ma->mii_flags; sc->mii_anegticks = MII_ANEGTICKS; sc->mii_funcs = &brgphy_funcs; if (device_is_a(parent, "bge")) bsc->sc_isbge = true; else if (device_is_a(parent, "bnx")) bsc->sc_isbnx = true; if (bsc->sc_isbge || bsc->sc_isbnx) { dict = device_properties(parent); if (!prop_dictionary_get_uint32(dict, "phyflags", &bsc->sc_phyflags)) aprint_error_dev(self, "failed to get phyflags\n"); if (!prop_dictionary_get_uint32(dict, "chipid", &bsc->sc_chipid)) aprint_error_dev(self, "failed to get chipid\n"); } PHY_RESET(sc); sc->mii_capabilities = PHY_READ(sc, MII_BMSR) & ma->mii_capmask; if (sc->mii_capabilities & BMSR_EXTSTAT) sc->mii_extcapabilities = PHY_READ(sc, MII_EXTSR); aprint_normal_dev(self, ""); if ((sc->mii_capabilities & BMSR_MEDIAMASK) == 0 && (sc->mii_extcapabilities & EXTSR_MEDIAMASK) == 0) aprint_error("no media present"); else { if (sc->mii_flags & MIIF_HAVEFIBER) { sc->mii_flags |= MIIF_NOISOLATE | MIIF_NOLOOP; /* * Set the proper bits for capabilities so that the * correct media get selected by mii_phy_add_media() */ sc->mii_capabilities |= BMSR_ANEG; sc->mii_capabilities &= ~BMSR_100T4; sc->mii_extcapabilities |= EXTSR_1000XFDX; if (bsc->sc_isbnx) { /* * 2.5Gb support is a software enabled feature * on the BCM5708S and BCM5709S controllers. */ #define ADD(m, c) ifmedia_add(&mii->mii_media, (m), (c), NULL) if (bsc->sc_phyflags & BNX_PHY_2_5G_CAPABLE_FLAG) { ADD(IFM_MAKEWORD(IFM_ETHER, IFM_2500_SX, IFM_FDX, sc->mii_inst), 0); aprint_normal("2500baseSX-FDX, "); #undef ADD } } } mii_phy_add_media(sc); } aprint_normal("\n"); }