diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2013-11-06 16:20:21 +0100 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2013-11-11 10:08:08 +0100 |
commit | 66659ff1ad6831b0ea7425fa6ecd8a8687523658 (patch) | |
tree | 48e22b475fa8854128e0861a33fed6f78c8094b5 /freebsd/sys/dev/mii | |
parent | Define __GLOBL1() and __GLOBL() (diff) | |
download | rtems-libbsd-66659ff1ad6831b0ea7425fa6ecd8a8687523658.tar.bz2 |
Update to FreeBSD 9.2
Diffstat (limited to 'freebsd/sys/dev/mii')
-rw-r--r-- | freebsd/sys/dev/mii/brgphy.c | 186 | ||||
-rw-r--r-- | freebsd/sys/dev/mii/icsphy.c | 67 | ||||
-rw-r--r-- | freebsd/sys/dev/mii/mii.c | 60 | ||||
-rw-r--r-- | freebsd/sys/dev/mii/mii.h | 4 | ||||
-rw-r--r-- | freebsd/sys/dev/mii/mii_physubr.c | 144 | ||||
-rw-r--r-- | freebsd/sys/dev/mii/miivar.h | 40 |
6 files changed, 208 insertions, 293 deletions
diff --git a/freebsd/sys/dev/mii/brgphy.c b/freebsd/sys/dev/mii/brgphy.c index e21e783e..de1249c3 100644 --- a/freebsd/sys/dev/mii/brgphy.c +++ b/freebsd/sys/dev/mii/brgphy.c @@ -70,9 +70,6 @@ static int brgphy_attach(device_t); struct brgphy_softc { struct mii_softc mii_sc; - int mii_oui; - int mii_model; - int mii_rev; int serdes_flags; /* Keeps track of the serdes type used */ #define BRGPHY_5706S 0x0001 #define BRGPHY_5708S 0x0002 @@ -119,39 +116,49 @@ static void brgphy_ethernet_wirespeed(struct mii_softc *); static void brgphy_jumbo_settings(struct mii_softc *, u_long); static const struct mii_phydesc brgphys[] = { - MII_PHY_DESC(xxBROADCOM, BCM5400), - MII_PHY_DESC(xxBROADCOM, BCM5401), - MII_PHY_DESC(xxBROADCOM, BCM5411), - MII_PHY_DESC(xxBROADCOM, BCM54K2), - MII_PHY_DESC(xxBROADCOM, BCM5701), - MII_PHY_DESC(xxBROADCOM, BCM5703), - MII_PHY_DESC(xxBROADCOM, BCM5704), - MII_PHY_DESC(xxBROADCOM, BCM5705), - MII_PHY_DESC(xxBROADCOM, BCM5706), - MII_PHY_DESC(xxBROADCOM, BCM5714), - MII_PHY_DESC(xxBROADCOM, BCM5750), - MII_PHY_DESC(xxBROADCOM, BCM5752), - MII_PHY_DESC(xxBROADCOM, BCM5754), - MII_PHY_DESC(xxBROADCOM, BCM5780), - MII_PHY_DESC(xxBROADCOM, BCM5708C), - MII_PHY_DESC(xxBROADCOM_ALT1, BCM5755), - MII_PHY_DESC(xxBROADCOM_ALT1, BCM5787), - MII_PHY_DESC(xxBROADCOM_ALT1, BCM5708S), - MII_PHY_DESC(xxBROADCOM_ALT1, BCM5709CAX), - MII_PHY_DESC(xxBROADCOM_ALT1, BCM5722), - MII_PHY_DESC(xxBROADCOM_ALT1, BCM5784), - MII_PHY_DESC(xxBROADCOM_ALT1, BCM5709C), - MII_PHY_DESC(xxBROADCOM_ALT1, BCM5761), - MII_PHY_DESC(xxBROADCOM_ALT1, BCM5709S), - MII_PHY_DESC(xxBROADCOM_ALT2, BCM5717C), - MII_PHY_DESC(xxBROADCOM_ALT2, BCM5719C), - MII_PHY_DESC(xxBROADCOM_ALT2, BCM5720C), - MII_PHY_DESC(xxBROADCOM_ALT2, BCM57765), - MII_PHY_DESC(xxBROADCOM_ALT2, BCM57780), - MII_PHY_DESC(BROADCOM2, BCM5906), + MII_PHY_DESC(BROADCOM, BCM5400), + MII_PHY_DESC(BROADCOM, BCM5401), + MII_PHY_DESC(BROADCOM, BCM5411), + MII_PHY_DESC(BROADCOM, BCM54K2), + MII_PHY_DESC(BROADCOM, BCM5701), + MII_PHY_DESC(BROADCOM, BCM5703), + MII_PHY_DESC(BROADCOM, BCM5704), + MII_PHY_DESC(BROADCOM, BCM5705), + MII_PHY_DESC(BROADCOM, BCM5706), + MII_PHY_DESC(BROADCOM, BCM5714), + MII_PHY_DESC(BROADCOM, BCM5421), + MII_PHY_DESC(BROADCOM, BCM5750), + MII_PHY_DESC(BROADCOM, BCM5752), + MII_PHY_DESC(BROADCOM, BCM5780), + MII_PHY_DESC(BROADCOM, BCM5708C), + MII_PHY_DESC(BROADCOM2, BCM5482), + MII_PHY_DESC(BROADCOM2, BCM5708S), + MII_PHY_DESC(BROADCOM2, BCM5709C), + MII_PHY_DESC(BROADCOM2, BCM5709S), + MII_PHY_DESC(BROADCOM2, BCM5709CAX), + MII_PHY_DESC(BROADCOM2, BCM5722), + MII_PHY_DESC(BROADCOM2, BCM5755), + MII_PHY_DESC(BROADCOM2, BCM5754), + MII_PHY_DESC(BROADCOM2, BCM5761), + MII_PHY_DESC(BROADCOM2, BCM5784), +#ifdef notyet /* better handled by ukphy(4) until WARs are implemented */ + MII_PHY_DESC(BROADCOM2, BCM5785), +#endif + MII_PHY_DESC(BROADCOM3, BCM5717C), + MII_PHY_DESC(BROADCOM3, BCM5719C), + MII_PHY_DESC(BROADCOM3, BCM5720C), + MII_PHY_DESC(BROADCOM3, BCM57765), + MII_PHY_DESC(BROADCOM3, BCM57780), + MII_PHY_DESC(xxBROADCOM_ALT1, BCM5906), MII_PHY_END }; +static const struct mii_phy_funcs brgphy_funcs = { + brgphy_service, + brgphy_status, + brgphy_reset +}; + #define HS21_PRODUCT_ID "IBM eServer BladeCenter HS21" #define HS21_BCM_CHIPID 0x57081021 @@ -190,41 +197,17 @@ brgphy_attach(device_t dev) 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; bsc = device_get_softc(dev); sc = &bsc->mii_sc; - 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); - - /* Initialize mii_softc structure */ - sc->mii_flags = miibus_get_flags(dev); - sc->mii_inst = mii->mii_instance++; - sc->mii_phy = ma->mii_phyno; - sc->mii_service = brgphy_service; - sc->mii_pdata = mii; - /* - * At least some variants wedge when isolating, at least some also - * don't support loopback. - */ - sc->mii_flags |= MIIF_NOISOLATE | MIIF_NOLOOP | MIIF_NOMANPAUSE; + mii_phy_dev_attach(dev, MIIF_NOISOLATE | MIIF_NOMANPAUSE, + &brgphy_funcs, 0); - /* 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; ifp = sc->mii_pdata->mii_ifp; - if (bootverbose) - device_printf(dev, "OUI 0x%06x, model 0x%04x, rev. %d\n", - bsc->mii_oui, bsc->mii_model, bsc->mii_rev); - /* Find the MAC driver associated with this PHY. */ if (strcmp(ifp->if_dname, "bge") == 0) bge_sc = ifp->if_softc; @@ -232,11 +215,11 @@ brgphy_attach(device_t dev) bce_sc = ifp->if_softc; /* Handle any special cases based on the PHY ID */ - switch (bsc->mii_oui) { - case MII_OUI_xxBROADCOM: - switch (bsc->mii_model) { - case MII_MODEL_xxBROADCOM_BCM5706: - case MII_MODEL_xxBROADCOM_BCM5714: + switch (sc->mii_mpd_oui) { + case MII_OUI_BROADCOM: + switch (sc->mii_mpd_model) { + case MII_MODEL_BROADCOM_BCM5706: + case MII_MODEL_BROADCOM_BCM5714: /* * The 5464 PHY used in the 5706 supports both copper * and fiber interfaces over GMII. Need to check the @@ -254,13 +237,13 @@ brgphy_attach(device_t dev) break; } break; - case MII_OUI_xxBROADCOM_ALT1: - switch (bsc->mii_model) { - case MII_MODEL_xxBROADCOM_ALT1_BCM5708S: + case MII_OUI_BROADCOM2: + switch (sc->mii_mpd_model) { + case MII_MODEL_BROADCOM2_BCM5708S: bsc->serdes_flags |= BRGPHY_5708S; sc->mii_flags |= MIIF_HAVEFIBER; break; - case MII_MODEL_xxBROADCOM_ALT1_BCM5709S: + case MII_MODEL_BROADCOM2_BCM5709S: /* * XXX * 5720S and 5709S shares the same PHY id. @@ -276,15 +259,15 @@ brgphy_attach(device_t dev) break; } - brgphy_reset(sc); + PHY_RESET(sc); /* Read the PHY's capabilities. */ - sc->mii_capabilities = PHY_READ(sc, MII_BMSR) & ma->mii_capmask; + 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, " "); -#define ADD(m, c) ifmedia_add(&mii->mii_media, (m), (c), NULL) +#define ADD(m, c) ifmedia_add(&sc->mii_pdata->mii_media, (m), (c), NULL) /* Add the supported media types */ if ((sc->mii_flags & MIIF_HAVEFIBER) == 0) { @@ -325,7 +308,6 @@ brgphy_attach(device_t dev) static int brgphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd) { - struct brgphy_softc *bsc = (struct brgphy_softc *)sc; struct ifmedia_entry *ife = mii->mii_media.ifm_cur; int val; @@ -338,7 +320,7 @@ brgphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd) break; /* Todo: Why is this here? Is it really needed? */ - brgphy_reset(sc); /* XXX hardware bug work-around */ + PHY_RESET(sc); /* XXX hardware bug work-around */ switch (IFM_SUBTYPE(ife->ifm_media)) { case IFM_AUTO: @@ -393,7 +375,7 @@ brgphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd) } /* Update the media status. */ - brgphy_status(sc); + PHY_STATUS(sc); /* * Callback if something changed. Note that we need to poke @@ -402,20 +384,20 @@ brgphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd) if (sc->mii_media_active != mii->mii_media_active || sc->mii_media_status != mii->mii_media_status || cmd == MII_MEDIACHG) { - switch (bsc->mii_oui) { - case MII_OUI_xxBROADCOM: - switch (bsc->mii_model) { - case MII_MODEL_xxBROADCOM_BCM5400: + switch (sc->mii_mpd_oui) { + case MII_OUI_BROADCOM: + switch (sc->mii_mpd_model) { + case MII_MODEL_BROADCOM_BCM5400: bcm5401_load_dspcode(sc); break; - case MII_MODEL_xxBROADCOM_BCM5401: - if (bsc->mii_rev == 1 || bsc->mii_rev == 3) + case MII_MODEL_BROADCOM_BCM5401: + if (sc->mii_mpd_rev == 1 || sc->mii_mpd_rev == 3) bcm5401_load_dspcode(sc); break; - case MII_MODEL_xxBROADCOM_BCM5411: + case MII_MODEL_BROADCOM_BCM5411: bcm5411_load_dspcode(sc); break; - case MII_MODEL_xxBROADCOM_BCM54K2: + case MII_MODEL_BROADCOM_BCM54K2: bcm54k2_load_dspcode(sc); break; } @@ -474,8 +456,7 @@ brgphy_setmedia(struct mii_softc *sc, int media) if (IFM_SUBTYPE(media) == IFM_1000_T) { gig |= BRGPHY_1000CTL_MSE; - if ((media & IFM_ETH_MASTER) != 0 || - (sc->mii_pdata->mii_ifp->if_flags & IFF_LINK0) != 0) + if ((media & IFM_ETH_MASTER) != 0) gig |= BRGPHY_1000CTL_MSC; } PHY_WRITE(sc, BRGPHY_MII_1000CTL, gig); @@ -625,10 +606,9 @@ brgphy_status(struct mii_softc *sc) static void brgphy_mii_phy_auto(struct mii_softc *sc, int media) { - struct brgphy_softc *bsc = (struct brgphy_softc *)sc; int anar, ktcr = 0; - brgphy_reset(sc); + PHY_RESET(sc); if ((sc->mii_flags & MIIF_HAVEFIBER) == 0) { anar = BMSR_MEDIA_TO_ANAR(sc->mii_capabilities) | ANAR_CSMA; @@ -637,7 +617,7 @@ brgphy_mii_phy_auto(struct mii_softc *sc, int media) anar |= BRGPHY_ANAR_PC | BRGPHY_ANAR_ASP; PHY_WRITE(sc, BRGPHY_MII_ANAR, anar); ktcr = BRGPHY_1000CTL_AFD | BRGPHY_1000CTL_AHD; - if (bsc->mii_model == MII_MODEL_xxBROADCOM_BCM5701) + if (sc->mii_mpd_model == MII_MODEL_BROADCOM_BCM5701) ktcr |= BRGPHY_1000CTL_MSE | BRGPHY_1000CTL_MSC; PHY_WRITE(sc, BRGPHY_MII_1000CTL, ktcr); PHY_READ(sc, BRGPHY_MII_1000CTL); @@ -874,12 +854,11 @@ brgphy_ethernet_wirespeed(struct mii_softc *sc) static void brgphy_jumbo_settings(struct mii_softc *sc, u_long mtu) { - struct brgphy_softc *bsc = (struct brgphy_softc *)sc; uint32_t val; /* Set or clear jumbo frame settings in the PHY. */ if (mtu > ETHER_MAX_LEN) { - if (bsc->mii_model == MII_MODEL_xxBROADCOM_BCM5401) { + if (sc->mii_mpd_model == MII_MODEL_BROADCOM_BCM5401) { /* BCM5401 PHY cannot read-modify-write. */ PHY_WRITE(sc, BRGPHY_MII_AUXCTL, 0x4c20); } else { @@ -907,7 +886,6 @@ brgphy_jumbo_settings(struct mii_softc *sc, u_long mtu) static void brgphy_reset(struct mii_softc *sc) { - struct brgphy_softc *bsc = (struct brgphy_softc *)sc; struct bge_softc *bge_sc = NULL; struct bce_softc *bce_sc = NULL; struct ifnet *ifp; @@ -929,30 +907,30 @@ brgphy_reset(struct mii_softc *sc) } /* Handle any PHY specific procedures following the reset. */ - switch (bsc->mii_oui) { - case MII_OUI_xxBROADCOM: - switch (bsc->mii_model) { - case MII_MODEL_xxBROADCOM_BCM5400: + switch (sc->mii_mpd_oui) { + case MII_OUI_BROADCOM: + switch (sc->mii_mpd_model) { + case MII_MODEL_BROADCOM_BCM5400: bcm5401_load_dspcode(sc); break; - case MII_MODEL_xxBROADCOM_BCM5401: - if (bsc->mii_rev == 1 || bsc->mii_rev == 3) + case MII_MODEL_BROADCOM_BCM5401: + if (sc->mii_mpd_rev == 1 || sc->mii_mpd_rev == 3) bcm5401_load_dspcode(sc); break; - case MII_MODEL_xxBROADCOM_BCM5411: + case MII_MODEL_BROADCOM_BCM5411: bcm5411_load_dspcode(sc); break; - case MII_MODEL_xxBROADCOM_BCM54K2: + case MII_MODEL_BROADCOM_BCM54K2: bcm54k2_load_dspcode(sc); break; } break; - case MII_OUI_xxBROADCOM_ALT2: - switch (bsc->mii_model) { - case MII_MODEL_xxBROADCOM_ALT2_BCM5717C: - case MII_MODEL_xxBROADCOM_ALT2_BCM5719C: - case MII_MODEL_xxBROADCOM_ALT2_BCM5720C: - case MII_MODEL_xxBROADCOM_ALT2_BCM57765: + case MII_OUI_BROADCOM3: + switch (sc->mii_mpd_model) { + case MII_MODEL_BROADCOM3_BCM5717C: + case MII_MODEL_BROADCOM3_BCM5719C: + case MII_MODEL_BROADCOM3_BCM5720C: + case MII_MODEL_BROADCOM3_BCM57765: return; } break; diff --git a/freebsd/sys/dev/mii/icsphy.c b/freebsd/sys/dev/mii/icsphy.c index 47474db7..3d5e6384 100644 --- a/freebsd/sys/dev/mii/icsphy.c +++ b/freebsd/sys/dev/mii/icsphy.c @@ -85,11 +85,6 @@ __FBSDID("$FreeBSD$"); static int icsphy_probe(device_t dev); static int icsphy_attach(device_t dev); -struct icsphy_softc { - struct mii_softc mii_sc; - int mii_model; -}; - static device_method_t icsphy_methods[] = { /* device interface */ DEVMETHOD(device_probe, icsphy_probe), @@ -104,7 +99,7 @@ static devclass_t icsphy_devclass; static driver_t icsphy_driver = { "icsphy", icsphy_methods, - sizeof(struct icsphy_softc) + sizeof(struct mii_softc) }; DRIVER_MODULE(icsphy, miibus, icsphy_driver, icsphy_devclass, 0, 0); @@ -114,13 +109,19 @@ static void icsphy_status(struct mii_softc *); static void icsphy_reset(struct mii_softc *); static const struct mii_phydesc icsphys[] = { - MII_PHY_DESC(xxICS, 1889), - MII_PHY_DESC(xxICS, 1890), - MII_PHY_DESC(xxICS, 1892), - MII_PHY_DESC(xxICS, 1893), + MII_PHY_DESC(ICS, 1889), + MII_PHY_DESC(ICS, 1890), + MII_PHY_DESC(ICS, 1892), + MII_PHY_DESC(ICS, 1893), MII_PHY_END }; +static const struct mii_phy_funcs icsphy_funcs = { + icsphy_service, + icsphy_status, + icsphy_reset +}; + static int icsphy_probe(device_t dev) { @@ -131,40 +132,9 @@ icsphy_probe(device_t dev) static int icsphy_attach(device_t dev) { - struct icsphy_softc *isc; - struct mii_softc *sc; - struct mii_attach_args *ma; - struct mii_data *mii; - - isc = device_get_softc(dev); - sc = &isc->mii_sc; - 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 = miibus_get_flags(dev); - sc->mii_inst = mii->mii_instance++; - sc->mii_phy = ma->mii_phyno; - sc->mii_service = icsphy_service; - sc->mii_pdata = mii; - - sc->mii_flags |= MIIF_NOISOLATE | MIIF_NOMANPAUSE; - - ifmedia_add(&mii->mii_media, - IFM_MAKEWORD(IFM_ETHER, IFM_100_TX, IFM_LOOP, sc->mii_inst), - MII_MEDIA_100_TX, NULL); - - isc->mii_model = MII_MODEL(ma->mii_id2); - icsphy_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); + mii_phy_dev_attach(dev, MIIF_NOISOLATE | MIIF_NOMANPAUSE, + &icsphy_funcs, 1); return (0); } @@ -193,7 +163,7 @@ icsphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd) } /* Update the media status. */ - icsphy_status(sc); + PHY_STATUS(sc); /* Callback if something changed. */ mii_phy_update(sc, cmd); @@ -253,16 +223,15 @@ icsphy_status(struct mii_softc *sc) static void icsphy_reset(struct mii_softc *sc) { - struct icsphy_softc *isc = (struct icsphy_softc *)sc; mii_phy_reset(sc); /* set powerdown feature */ - switch (isc->mii_model) { - case MII_MODEL_xxICS_1890: - case MII_MODEL_xxICS_1893: + switch (sc->mii_mpd_model) { + case MII_MODEL_ICS_1890: + case MII_MODEL_ICS_1893: PHY_WRITE(sc, MII_ICSPHY_ECR2, ECR2_100AUTOPWRDN); break; - case MII_MODEL_xxICS_1892: + case MII_MODEL_ICS_1892: PHY_WRITE(sc, MII_ICSPHY_ECR2, ECR2_10AUTOPWRDN|ECR2_100AUTOPWRDN); break; diff --git a/freebsd/sys/dev/mii/mii.c b/freebsd/sys/dev/mii/mii.c index e3a3ec84..d1f55cb0 100644 --- a/freebsd/sys/dev/mii/mii.c +++ b/freebsd/sys/dev/mii/mii.c @@ -72,6 +72,7 @@ static miibus_writereg_t miibus_writereg; static miibus_linkchg_t miibus_linkchg; static miibus_mediainit_t miibus_mediainit; +static unsigned char mii_bitreverse(unsigned char x); static device_method_t miibus_methods[] = { /* device interface */ @@ -303,19 +304,12 @@ miibus_statchg(device_t dev) { device_t parent; struct mii_data *mii; - struct ifnet *ifp; parent = device_get_parent(dev); MIIBUS_STATCHG(parent); mii = device_get_softc(dev); - - /* - * Note that each NIC's softc must start with an ifnet pointer. - * XXX: EVIL HACK! - */ - ifp = *(struct ifnet **)device_get_softc(parent); - ifp->if_baudrate = ifmedia_baudrate(mii->mii_media_active); + mii->mii_ifp->if_baudrate = ifmedia_baudrate(mii->mii_media_active); } static void @@ -337,11 +331,7 @@ miibus_linkchg(device_t dev) link_state = LINK_STATE_DOWN; } else link_state = LINK_STATE_UNKNOWN; - /* - * Note that each NIC's softc must start with an ifnet pointer. - * XXX: EVIL HACK! - */ - if_link_state_change(*(struct ifnet**)device_get_softc(parent), link_state); + if_link_state_change(mii->mii_ifp, link_state); } static void @@ -493,6 +483,7 @@ mii_attach(device_t dev, device_t *miibus, struct ifnet *ifp, ma.mii_id1 = MIIBUS_READREG(dev, ma.mii_phyno, MII_PHYIDR1); ma.mii_id2 = MIIBUS_READREG(dev, ma.mii_phyno, MII_PHYIDR2); + ma.mii_offset = ivars->mii_offset; args = malloc(sizeof(struct mii_attach_args), M_DEVBUF, M_NOWAIT); if (args == NULL) @@ -544,21 +535,6 @@ mii_attach(device_t dev, device_t *miibus, struct ifnet *ifp, return (rv); } -int -mii_phy_probe(device_t dev, device_t *child, ifm_change_cb_t ifmedia_upd, - ifm_stat_cb_t ifmedia_sts) -{ - struct ifnet *ifp; - - /* - * Note that each NIC's softc must start with an ifnet pointer. - * XXX: EVIL HACK! - */ - ifp = *(struct ifnet **)device_get_softc(dev); - return (mii_attach(dev, child, ifp, ifmedia_upd, ifmedia_sts, - BMSR_DEFCAPMASK, MII_PHY_ANY, MII_OFFSET_ANY, 0)); -} - /* * Media changed; notify all PHYs. */ @@ -588,7 +564,7 @@ mii_mediachg(struct mii_data *mii) BMCR_ISO); continue; } - rv = (*child->mii_service)(child, mii, MII_MEDIACHG); + rv = PHY_SERVICE(child, mii, MII_MEDIACHG); if (rv) return (rv); } @@ -611,7 +587,7 @@ mii_tick(struct mii_data *mii) */ if (IFM_INST(ife->ifm_media) != child->mii_inst) continue; - (void)(*child->mii_service)(child, mii, MII_TICK); + (void)PHY_SERVICE(child, mii, MII_TICK); } } @@ -633,7 +609,7 @@ mii_pollstat(struct mii_data *mii) */ if (IFM_INST(ife->ifm_media) != child->mii_inst) continue; - (void)(*child->mii_service)(child, mii, MII_POLLSTAT); + (void)PHY_SERVICE(child, mii, MII_POLLSTAT); } } @@ -648,3 +624,25 @@ mii_down(struct mii_data *mii) LIST_FOREACH(child, &mii->mii_phys, mii_list) mii_phy_down(child); } + +static unsigned char +mii_bitreverse(unsigned char x) +{ + static unsigned const char nibbletab[16] = { + 0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15 + }; + + return ((nibbletab[x & 15] << 4) | nibbletab[x >> 4]); +} + +u_int +mii_oui(u_int id1, u_int id2) +{ + u_int h; + + h = (id1 << 6) | (id2 >> 10); + + return ((mii_bitreverse(h >> 16) << 16) | + (mii_bitreverse((h >> 8) & 0xff) << 8) | + mii_bitreverse(h & 0xff)); +} diff --git a/freebsd/sys/dev/mii/mii.h b/freebsd/sys/dev/mii/mii.h index 5316f1eb..668fb8fb 100644 --- a/freebsd/sys/dev/mii/mii.h +++ b/freebsd/sys/dev/mii/mii.h @@ -106,10 +106,6 @@ #define IDR2_MODEL 0x03f0 /* vendor model */ #define IDR2_REV 0x000f /* vendor revision */ -#define MII_OUI(id1, id2) (((id1) << 6) | ((id2) >> 10)) -#define MII_MODEL(id2) (((id2) & IDR2_MODEL) >> 4) -#define MII_REV(id2) ((id2) & IDR2_REV) - #define MII_ANAR 0x04 /* Autonegotiation advertisement (rw) */ /* section 28.2.4.1 and 37.2.6.1 */ #define ANAR_NP 0x8000 /* Next page (ro) */ diff --git a/freebsd/sys/dev/mii/mii_physubr.c b/freebsd/sys/dev/mii/mii_physubr.c index 7fc4135c..e2725ba6 100644 --- a/freebsd/sys/dev/mii/mii_physubr.c +++ b/freebsd/sys/dev/mii/mii_physubr.c @@ -58,7 +58,7 @@ __FBSDID("$FreeBSD$"); /* * Media to register setting conversion table. Order matters. */ -const struct mii_media mii_media_table[MII_NMEDIA] = { +static const struct mii_media mii_media_table[MII_NMEDIA] = { /* None */ { BMCR_ISO, ANAR_CSMA, 0, }, @@ -152,9 +152,6 @@ mii_phy_setmedia(struct mii_softc *sc) } } - 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) @@ -253,7 +250,7 @@ mii_phy_tick(struct mii_softc *sc) return (EJUSTRETURN); sc->mii_ticks = 0; - mii_phy_reset(sc); + PHY_RESET(sc); mii_phy_auto(sc); return (0); } @@ -311,99 +308,6 @@ mii_phy_update(struct mii_softc *sc, int cmd) } /* - * Given an ifmedia word, return the corresponding ANAR value. - */ -int -mii_anar(int media) -{ - int rv; - - switch (media & (IFM_TMASK|IFM_NMASK|IFM_FDX)) { - case IFM_ETHER|IFM_10_T: - rv = ANAR_10|ANAR_CSMA; - break; - case IFM_ETHER|IFM_10_T|IFM_FDX: - rv = ANAR_10_FD|ANAR_CSMA; - break; - case IFM_ETHER|IFM_100_TX: - rv = ANAR_TX|ANAR_CSMA; - break; - case IFM_ETHER|IFM_100_TX|IFM_FDX: - rv = ANAR_TX_FD|ANAR_CSMA; - break; - case IFM_ETHER|IFM_100_T4: - rv = ANAR_T4|ANAR_CSMA; - break; - default: - rv = 0; - break; - } - - return (rv); -} - -/* - * Initialize generic PHY media based on BMSR, called when a PHY is - * attached. We expect to be set up to print a comma-separated list - * of media names. Does not print a newline. - */ -void -mii_add_media(struct mii_softc *sc) -{ - struct mii_data *mii = sc->mii_pdata; - const char *sep = ""; - - if ((sc->mii_capabilities & BMSR_MEDIAMASK) == 0) { - printf("no media present"); - return; - } - -#define ADD(m, c) ifmedia_add(&mii->mii_media, (m), (c), NULL) -#define PRINT(s) printf("%s%s", sep, s); sep = ", " - - if (sc->mii_capabilities & BMSR_10THDX) { - ADD(IFM_MAKEWORD(IFM_ETHER, IFM_10_T, 0, sc->mii_inst), 0); - PRINT("10baseT"); - } - if (sc->mii_capabilities & BMSR_10TFDX) { - ADD(IFM_MAKEWORD(IFM_ETHER, IFM_10_T, IFM_FDX, sc->mii_inst), - BMCR_FDX); - PRINT("10baseT-FDX"); - } - if (sc->mii_capabilities & BMSR_100TXHDX) { - ADD(IFM_MAKEWORD(IFM_ETHER, IFM_100_TX, 0, sc->mii_inst), - BMCR_S100); - PRINT("100baseTX"); - } - if (sc->mii_capabilities & BMSR_100TXFDX) { - ADD(IFM_MAKEWORD(IFM_ETHER, IFM_100_TX, IFM_FDX, sc->mii_inst), - BMCR_S100|BMCR_FDX); - PRINT("100baseTX-FDX"); - } - if (sc->mii_capabilities & BMSR_100T4) { - /* - * XXX How do you enable 100baseT4? I assume we set - * XXX BMCR_S100 and then assume the PHYs will take - * XXX watever action is necessary to switch themselves - * XXX into T4 mode. - */ - ADD(IFM_MAKEWORD(IFM_ETHER, IFM_100_T4, 0, sc->mii_inst), - BMCR_S100); - PRINT("100baseT4"); - } - if (sc->mii_capabilities & BMSR_ANEG) { - ADD(IFM_MAKEWORD(IFM_ETHER, IFM_AUTO, 0, sc->mii_inst), - BMCR_AUTOEN); - PRINT("auto"); - } - - - -#undef ADD -#undef PRINT -} - -/* * Initialize generic PHY media based on BMSR, called when a PHY is * attached. We expect to be set up to print a comma-separated list * of media names. Does not print a newline. @@ -621,6 +525,50 @@ mii_phy_dev_probe(device_t dev, const struct mii_phydesc *mpd, int mrv) return (ENXIO); } +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); +} + /* * Return the flow control status flag from MII_ANAR & MII_ANLPAR. */ diff --git a/freebsd/sys/dev/mii/miivar.h b/freebsd/sys/dev/mii/miivar.h index ac58ac20..34b0e9ed 100644 --- a/freebsd/sys/dev/mii/miivar.h +++ b/freebsd/sys/dev/mii/miivar.h @@ -83,10 +83,13 @@ struct mii_data { typedef struct mii_data mii_data_t; /* - * This call is used by the MII layer to call into the PHY driver - * to perform a `service request'. + * Functions provided by the PHY to perform various functions. */ -typedef int (*mii_downcall_t)(struct mii_softc *, struct mii_data *, int); +struct mii_phy_funcs { + int (*pf_service)(struct mii_softc *, struct mii_data *, int); + void (*pf_status)(struct mii_softc *); + void (*pf_reset)(struct mii_softc *); +}; /* * Requests that can be made to the downcall. @@ -105,10 +108,17 @@ struct mii_softc { LIST_ENTRY(mii_softc) mii_list; /* entry on parent's PHY list */ + uint32_t mii_mpd_oui; /* the PHY's OUI (MII_OUI())*/ + uint32_t mii_mpd_model; /* the PHY's model (MII_MODEL())*/ + uint32_t mii_mpd_rev; /* the PHY's revision (MII_REV())*/ + u_int mii_capmask; /* capability mask for BMSR */ u_int mii_phy; /* our MII address */ + u_int mii_offset; /* first PHY, second PHY, etc. */ u_int mii_inst; /* instance for ifmedia */ - mii_downcall_t mii_service; /* our downcall */ + /* Our PHY functions. */ + const struct mii_phy_funcs *mii_funcs; + struct mii_data *mii_pdata; /* pointer to parent's mii_data */ u_int mii_flags; /* misc. flags; see below */ @@ -124,7 +134,9 @@ typedef struct mii_softc mii_softc_t; /* mii_flags */ #define MIIF_INITDONE 0x00000001 /* has been initialized (mii_data) */ #define MIIF_NOISOLATE 0x00000002 /* do not isolate the PHY */ +#if 0 #define MIIF_NOLOOP 0x00000004 /* no loopback capability */ +#endif #define MIIF_DOINGAUTO 0x00000008 /* doing autonegotiation (mii_softc) */ #define MIIF_AUTOTSLEEP 0x00000010 /* use tsleep(), not callout() */ #define MIIF_HAVEFIBER 0x00000020 /* from parent: has fiber interface */ @@ -210,6 +222,15 @@ struct mii_media { #define PHY_WRITE(p, r, v) \ MIIBUS_WRITEREG((p)->mii_dev, (p)->mii_phy, (r), (v)) +#define PHY_SERVICE(p, d, o) \ + (*(p)->mii_funcs->pf_service)((p), (d), (o)) + +#define PHY_STATUS(p) \ + (*(p)->mii_funcs->pf_status)(p) + +#define PHY_RESET(p) \ + (*(p)->mii_funcs->pf_reset)(p) + enum miibus_device_ivars { MIIBUS_IVAR_FLAGS }; @@ -227,13 +248,10 @@ extern driver_t miibus_driver; int mii_attach(device_t, device_t *, struct ifnet *, ifm_change_cb_t, ifm_stat_cb_t, int, int, int, int); -int mii_anar(int); void mii_down(struct mii_data *); int mii_mediachg(struct mii_data *); void mii_tick(struct mii_data *); void mii_pollstat(struct mii_data *); -int mii_phy_probe(device_t, device_t *, ifm_change_cb_t, ifm_stat_cb_t); -void mii_add_media(struct mii_softc *); void mii_phy_add_media(struct mii_softc *); int mii_phy_auto(struct mii_softc *); @@ -250,8 +268,16 @@ const struct mii_phydesc * mii_phy_match(const struct mii_attach_args *ma, const struct mii_phydesc * mii_phy_match_gen(const struct mii_attach_args *ma, const struct mii_phydesc *mpd, size_t endlen); int mii_phy_dev_probe(device_t dev, const struct mii_phydesc *mpd, int mrv); +void mii_phy_dev_attach(device_t dev, u_int flags, + const struct mii_phy_funcs *mpf, int add_media); void ukphy_status(struct mii_softc *); + +u_int mii_oui(u_int, u_int); +#define MII_OUI(id1, id2) mii_oui(id1, id2) +#define MII_MODEL(id2) (((id2) & IDR2_MODEL) >> 4) +#define MII_REV(id2) ((id2) & IDR2_REV) + #endif /* _KERNEL */ #endif /* _DEV_MII_MIIVAR_H_ */ |