diff options
Diffstat (limited to 'freebsd/sys/dev/mii/brgphy.c')
-rw-r--r-- | freebsd/sys/dev/mii/brgphy.c | 95 |
1 files changed, 52 insertions, 43 deletions
diff --git a/freebsd/sys/dev/mii/brgphy.c b/freebsd/sys/dev/mii/brgphy.c index 75c15774..e07cd968 100644 --- a/freebsd/sys/dev/mii/brgphy.c +++ b/freebsd/sys/dev/mii/brgphy.c @@ -45,8 +45,10 @@ __FBSDID("$FreeBSD$"); #include <sys/module.h> #include <sys/socket.h> #include <sys/bus.h> +#include <sys/taskqueue.h> #include <net/if.h> +#include <net/if_var.h> #include <net/ethernet.h> #include <net/if_media.h> @@ -118,7 +120,10 @@ static void brgphy_jumbo_settings(struct mii_softc *, u_long); static const struct mii_phydesc brgphys[] = { MII_PHY_DESC(BROADCOM, BCM5400), MII_PHY_DESC(BROADCOM, BCM5401), + MII_PHY_DESC(BROADCOM, BCM5402), MII_PHY_DESC(BROADCOM, BCM5411), + MII_PHY_DESC(BROADCOM, BCM5404), + MII_PHY_DESC(BROADCOM, BCM5424), MII_PHY_DESC(BROADCOM, BCM54K2), MII_PHY_DESC(BROADCOM, BCM5701), MII_PHY_DESC(BROADCOM, BCM5703), @@ -131,6 +136,9 @@ static const struct mii_phydesc brgphys[] = { MII_PHY_DESC(BROADCOM, BCM5752), MII_PHY_DESC(BROADCOM, BCM5780), MII_PHY_DESC(BROADCOM, BCM5708C), + MII_PHY_DESC(BROADCOM, BCM5466), + MII_PHY_DESC(BROADCOM2, BCM5478), + MII_PHY_DESC(BROADCOM2, BCM5488), MII_PHY_DESC(BROADCOM2, BCM5482), MII_PHY_DESC(BROADCOM2, BCM5708S), MII_PHY_DESC(BROADCOM2, BCM5709C), @@ -160,25 +168,33 @@ static const struct mii_phy_funcs brgphy_funcs = { brgphy_reset }; -#define HS21_PRODUCT_ID "IBM eServer BladeCenter HS21" -#define HS21_BCM_CHIPID 0x57081021 +static const struct hs21_type { + const uint32_t id; + const char *prod; +} hs21_type_lists[] = { + { 0x57081021, "IBM eServer BladeCenter HS21" }, + { 0x57081011, "IBM eServer BladeCenter HS21 -[8853PAU]-" }, +}; static int detect_hs21(struct bce_softc *bce_sc) { char *sysenv; - int found; + int found, i; found = 0; - if (bce_sc->bce_chipid == HS21_BCM_CHIPID) { - sysenv = getenv("smbios.system.product"); - if (sysenv != NULL) { - if (strncmp(sysenv, HS21_PRODUCT_ID, - strlen(HS21_PRODUCT_ID)) == 0) - found = 1; - freeenv(sysenv); + sysenv = kern_getenv("smbios.system.product"); + if (sysenv == NULL) + return (found); + for (i = 0; i < nitems(hs21_type_lists); i++) { + if (bce_sc->bce_chipid == hs21_type_lists[i].id && + strncmp(sysenv, hs21_type_lists[i].prod, + strlen(hs21_type_lists[i].prod)) == 0) { + found++; + break; } } + freeenv(sysenv); return (found); } @@ -198,7 +214,6 @@ brgphy_attach(device_t dev) struct bge_softc *bge_sc = NULL; struct bce_softc *bce_sc = NULL; struct mii_softc *sc; - struct ifnet *ifp; bsc = device_get_softc(dev); sc = &bsc->mii_sc; @@ -207,13 +222,12 @@ brgphy_attach(device_t dev) &brgphy_funcs, 0); bsc->serdes_flags = 0; - 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; + if (mii_dev_mac_match(dev, "bge")) + bge_sc = mii_dev_mac_softc(dev); + else if (mii_dev_mac_match(dev, "bce")) + bce_sc = mii_dev_mac_softc(dev); /* Handle any special cases based on the PHY ID */ switch (sc->mii_mpd_oui) { @@ -268,20 +282,25 @@ brgphy_attach(device_t dev) sc->mii_extcapabilities = PHY_READ(sc, MII_EXTSR); device_printf(dev, " "); -#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) { mii_phy_add_media(sc); printf("\n"); } else { sc->mii_anegticks = MII_ANEGTICKS_GIGE; - ADD(IFM_MAKEWORD(IFM_ETHER, IFM_1000_SX, IFM_FDX, sc->mii_inst), - BRGPHY_S1000 | BRGPHY_BMCR_FDX); + ifmedia_add(&sc->mii_pdata->mii_media, + IFM_MAKEWORD(IFM_ETHER, IFM_1000_SX, IFM_FDX, sc->mii_inst), + 0, NULL); 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); + /* + * 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)) { + ifmedia_add(&sc->mii_pdata->mii_media, + IFM_MAKEWORD(IFM_ETHER, IFM_2500_SX, IFM_FDX, + sc->mii_inst), 0, NULL); printf("2500baseSX-FDX, "); } else if ((bsc->serdes_flags & BRGPHY_5708S) && bce_sc && (detect_hs21(bce_sc) != 0)) { @@ -297,11 +316,11 @@ brgphy_attach(device_t dev) printf("auto-neg workaround, "); bsc->serdes_flags |= BRGPHY_NOANWAIT; } - ADD(IFM_MAKEWORD(IFM_ETHER, IFM_AUTO, 0, sc->mii_inst), 0); + ifmedia_add(&sc->mii_pdata->mii_media, IFM_MAKEWORD(IFM_ETHER, + IFM_AUTO, 0, sc->mii_inst), 0, NULL); printf("auto\n"); } -#undef ADD MIIBUS_MEDIAINIT(sc->mii_dev); return (0); } @@ -316,10 +335,6 @@ brgphy_service(struct mii_softc *sc, struct mii_data *mii, int 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; - /* Todo: Why is this here? Is it really needed? */ PHY_RESET(sc); /* XXX hardware bug work-around */ @@ -339,11 +354,6 @@ brgphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd) } break; case MII_TICK: - /* Bail if the interface isn't up. */ - if ((mii->mii_ifp->if_flags & IFF_UP) == 0) - return (0); - - /* Bail if autoneg isn't in process. */ if (IFM_SUBTYPE(ife->ifm_media) != IFM_AUTO) { sc->mii_ticks = 0; @@ -889,7 +899,7 @@ brgphy_reset(struct mii_softc *sc) { struct bge_softc *bge_sc = NULL; struct bce_softc *bce_sc = NULL; - struct ifnet *ifp; + if_t ifp; int i, val; /* @@ -942,11 +952,10 @@ brgphy_reset(struct mii_softc *sc) ifp = sc->mii_pdata->mii_ifp; /* Find the 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; - } + if (mii_phy_mac_match(sc, "bge")) + bge_sc = mii_phy_mac_softc(sc); + else if (mii_phy_mac_match(sc, "bce")) + bce_sc = mii_phy_mac_softc(sc); if (bge_sc) { /* Fix up various bugs */ @@ -964,7 +973,7 @@ brgphy_reset(struct mii_softc *sc) brgphy_fixup_jitter_bug(sc); if (bge_sc->bge_flags & BGE_FLAG_JUMBO) - brgphy_jumbo_settings(sc, ifp->if_mtu); + brgphy_jumbo_settings(sc, if_getmtu(ifp)); if ((bge_sc->bge_phy_flags & BGE_PHY_NO_WIRESPEED) == 0) brgphy_ethernet_wirespeed(sc); @@ -1075,11 +1084,11 @@ brgphy_reset(struct mii_softc *sc) (BCE_CHIP_REV(bce_sc) == BCE_CHIP_REV_Bx)) brgphy_fixup_disable_early_dac(sc); - brgphy_jumbo_settings(sc, ifp->if_mtu); + brgphy_jumbo_settings(sc, if_getmtu(ifp)); brgphy_ethernet_wirespeed(sc); } else { brgphy_fixup_ber_bug(sc); - brgphy_jumbo_settings(sc, ifp->if_mtu); + brgphy_jumbo_settings(sc, if_getmtu(ifp)); brgphy_ethernet_wirespeed(sc); } } |