Пример #1
0
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);
}
Пример #2
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);
}
Пример #3
0
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);
}
Пример #4
0
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);
}
Пример #5
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;
}
Пример #6
0
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);
}
Пример #7
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);
}
Пример #8
0
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);
}
Пример #9
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);
}
Пример #10
0
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);
}
Пример #11
0
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");
}
Пример #12
0
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);
}
Пример #13
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);
}
Пример #14
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);
}
Пример #15
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);
}
Пример #16
0
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);
}
Пример #17
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);
}
Пример #18
0
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);
}
Пример #19
0
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);
}
Пример #20
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++;

	/*
	 * 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);
}
Пример #21
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");
}
Пример #22
0
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);
}
Пример #23
0
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
}
Пример #24
0
/* 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);
}
Пример #25
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");

}