Index: head/sys/dev/mii/brgphy.c =================================================================== --- head/sys/dev/mii/brgphy.c (revision 205298) +++ head/sys/dev/mii/brgphy.c (revision 205299) @@ -1,1107 +1,1186 @@ /*- * Copyright (c) 2000 * Bill Paul . All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by Bill Paul. * 4. Neither the name of the author nor the names of any co-contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. */ #include __FBSDID("$FreeBSD$"); /* * Driver for the Broadcom BCM54xx/57xx 1000baseTX PHY. */ #include #include #include #include #include #include #include #include #include #include #include #include "miidevs.h" #include #include #include #include #include #include #include #include "miibus_if.h" static int brgphy_probe(device_t); 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 #define BRGPHY_NOANWAIT 0x0004 +#define BRGPHY_5709S 0x0008 int bce_phy_flags; /* PHY flags transferred from the MAC driver */ }; static device_method_t brgphy_methods[] = { /* device interface */ DEVMETHOD(device_probe, brgphy_probe), DEVMETHOD(device_attach, brgphy_attach), DEVMETHOD(device_detach, mii_phy_detach), DEVMETHOD(device_shutdown, bus_generic_shutdown), { 0, 0 } }; static devclass_t brgphy_devclass; static driver_t brgphy_driver = { "brgphy", brgphy_methods, sizeof(struct brgphy_softc) }; DRIVER_MODULE(brgphy, miibus, brgphy_driver, brgphy_devclass, 0, 0); static int brgphy_service(struct mii_softc *, struct mii_data *, int); static void brgphy_setmedia(struct mii_softc *, int, int); static void brgphy_status(struct mii_softc *); static void brgphy_mii_phy_auto(struct mii_softc *); static void brgphy_reset(struct mii_softc *); static void brgphy_enable_loopback(struct mii_softc *); static void bcm5401_load_dspcode(struct mii_softc *); static void bcm5411_load_dspcode(struct mii_softc *); static void bcm54k2_load_dspcode(struct mii_softc *); static void brgphy_fixup_5704_a0_bug(struct mii_softc *); static void brgphy_fixup_adc_bug(struct mii_softc *); static void brgphy_fixup_adjust_trim(struct mii_softc *); static void brgphy_fixup_ber_bug(struct mii_softc *); static void brgphy_fixup_crc_bug(struct mii_softc *); static void brgphy_fixup_jitter_bug(struct mii_softc *); 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(BROADCOM2, BCM5906), MII_PHY_END }; #define HS21_PRODUCT_ID "IBM eServer BladeCenter HS21" #define HS21_BCM_CHIPID 0x57081021 static int detect_hs21(struct bce_softc *bce_sc) { char *sysenv; if (bce_sc->bce_chipid != HS21_BCM_CHIPID) return (0); sysenv = getenv("smbios.system.product"); if (sysenv == NULL) return (0); if (strncmp(sysenv, HS21_PRODUCT_ID, strlen(HS21_PRODUCT_ID)) != 0) return (0); return (1); } /* Search for our PHY in the list of known PHYs */ static int brgphy_probe(device_t dev) { return (mii_phy_dev_probe(dev, brgphys, BUS_PROBE_DEFAULT)); } /* 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: - case MII_MODEL_xxBROADCOM_BCM5714: - /* - * 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; + case MII_MODEL_xxBROADCOM_BCM5706: + case MII_MODEL_xxBROADCOM_BCM5714: + /* + * 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; + case MII_MODEL_xxBROADCOM_ALT1_BCM5708S: + bsc->serdes_flags |= BRGPHY_5708S; + sc->mii_flags |= MIIF_HAVEFIBER; + break; + case MII_MODEL_xxBROADCOM_ALT1_BCM5709S: + bsc->serdes_flags |= BRGPHY_5709S; + 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, "); } else if ((bsc->serdes_flags & BRGPHY_5708S) && bce_sc && (detect_hs21(bce_sc) != 0)) { /* * There appears to be certain silicon revision * in IBM HS21 blades that is having issues with * this driver wating for the auto-negotiation to * complete. This happens with a specific chip id * only and when the 1000baseSX-FDX is the only * mode. Workaround this issue since it's unlikely * to be ever addressed. */ printf("auto-neg workaround, "); bsc->serdes_flags |= BRGPHY_NOANWAIT; } } 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 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 error = 0; int val; switch (cmd) { case MII_POLLSTAT: /* If we're not polling our PHY instance, just return. */ if (IFM_INST(ife->ifm_media) != sc->mii_inst) goto brgphy_service_exit; break; case MII_MEDIACHG: /* * If the media indicates a different PHY instance, * isolate ourselves. */ if (IFM_INST(ife->ifm_media) != sc->mii_inst) { PHY_WRITE(sc, MII_BMCR, PHY_READ(sc, MII_BMCR) | BMCR_ISO); goto brgphy_service_exit; } /* 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? */ brgphy_reset(sc); /* XXX hardware bug work-around */ switch (IFM_SUBTYPE(ife->ifm_media)) { case IFM_AUTO: brgphy_mii_phy_auto(sc); break; case IFM_2500_SX: case IFM_1000_SX: case IFM_1000_T: case IFM_100_TX: case IFM_10_T: brgphy_setmedia(sc, ife->ifm_media, mii->mii_ifp->if_flags & IFF_LINK0); break; default: error = EINVAL; goto brgphy_service_exit; } break; case MII_TICK: /* Bail if we're not currently selected. */ if (IFM_INST(ife->ifm_media) != sc->mii_inst) goto brgphy_service_exit; /* Bail if the interface isn't up. */ if ((mii->mii_ifp->if_flags & IFF_UP) == 0) goto brgphy_service_exit; /* Bail if autoneg isn't in process. */ if (IFM_SUBTYPE(ife->ifm_media) != IFM_AUTO) { sc->mii_ticks = 0; break; } /* * Check to see if we have link. If we do, we don't * need to restart the autonegotiation process. */ val = PHY_READ(sc, MII_BMSR) | PHY_READ(sc, MII_BMSR); if (val & BMSR_LINK) { sc->mii_ticks = 0; /* Reset autoneg timer. */ break; } /* Announce link loss right after it happens. */ if (sc->mii_ticks++ == 0) break; /* Only retry autonegotiation every mii_anegticks seconds. */ if (sc->mii_ticks <= sc->mii_anegticks) break; /* Retry autonegotiation */ sc->mii_ticks = 0; brgphy_mii_phy_auto(sc); break; } /* Update the media status. */ brgphy_status(sc); /* * Callback if something changed. Note that we need to poke * the DSP on the Broadcom PHYs if the media changes. */ 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_BROADCOM: break; case MII_OUI_xxBROADCOM: switch (bsc->mii_model) { case MII_MODEL_xxBROADCOM_BCM5400: bcm5401_load_dspcode(sc); break; case MII_MODEL_xxBROADCOM_BCM5401: if (bsc->mii_rev == 1 || bsc->mii_rev == 3) bcm5401_load_dspcode(sc); break; case MII_MODEL_xxBROADCOM_BCM5411: bcm5411_load_dspcode(sc); break; case MII_MODEL_xxBROADCOM_BCM54K2: bcm54k2_load_dspcode(sc); break; } break; case MII_OUI_xxBROADCOM_ALT1: break; } } mii_phy_update(sc, cmd); brgphy_service_exit: return (error); } /****************************************************************************/ /* Sets the PHY link speed. */ /* */ /* Returns: */ /* None */ /****************************************************************************/ static void brgphy_setmedia(struct mii_softc *sc, int media, int master) { struct brgphy_softc *bsc = (struct brgphy_softc *)sc; int bmcr = 0, gig; /* Calculate the value for the BMCR register. */ 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; } /* Calculate duplex settings for 1000BasetT/1000BaseX. */ if ((media & IFM_GMASK) == IFM_FDX) { bmcr |= BRGPHY_BMCR_FDX; gig = BRGPHY_1000CTL_AFD; } else { gig = BRGPHY_1000CTL_AHD; } /* Force loopback to disconnect PHY for Ethernet medium. */ brgphy_enable_loopback(sc); /* Disable 1000BaseT advertisements. */ PHY_WRITE(sc, BRGPHY_MII_1000CTL, 0); /* Disable 10/100 advertisements. */ PHY_WRITE(sc, BRGPHY_MII_ANAR, BRGPHY_SEL_TYPE); /* Write forced link speed. */ PHY_WRITE(sc, BRGPHY_MII_BMCR, bmcr); /* If 10/100 only then configuration is complete. */ if ((IFM_SUBTYPE(media) != IFM_1000_T) && (IFM_SUBTYPE(media) != IFM_1000_SX)) goto brgphy_setmedia_exit; /* Set duplex speed advertisement for 1000BaseT/1000BaseX. */ PHY_WRITE(sc, BRGPHY_MII_1000CTL, gig); /* Restart auto-negotiation for 1000BaseT/1000BaseX. */ PHY_WRITE(sc, BRGPHY_MII_BMCR, bmcr | BRGPHY_BMCR_AUTOEN | BRGPHY_BMCR_STARTNEG); /* If not 5701 PHY then configuration is complete. */ if (bsc->mii_model != MII_MODEL_xxBROADCOM_BCM5701) goto brgphy_setmedia_exit; /* * When setting the link manually, one side must be the master and * the other the slave. However ifmedia doesn't give us a good way * to specify this, so we fake it by using one of the LINK flags. * If LINK0 is set, we program the PHY to be a master, otherwise * it's a slave. */ if (master) { PHY_WRITE(sc, BRGPHY_MII_1000CTL, gig | BRGPHY_1000CTL_MSE | BRGPHY_1000CTL_MSC); } else { PHY_WRITE(sc, BRGPHY_MII_1000CTL, gig | BRGPHY_1000CTL_MSE); } brgphy_setmedia_exit: return; } /****************************************************************************/ /* Set the media status based on the PHY settings. */ /* IFM_FLAG0 = 0 (RX flow control disabled) | 1 (enabled) */ /* IFM_FLAG1 = 0 (TX flow control disabled) | 1 (enabled) */ /* */ /* Returns: */ /* None */ /****************************************************************************/ static void brgphy_status(struct mii_softc *sc) { struct brgphy_softc *bsc = (struct brgphy_softc *)sc; struct mii_data *mii = sc->mii_pdata; int aux, bmcr, bmsr, anar, anlpar, xstat, val; mii->mii_media_status = IFM_AVALID; mii->mii_media_active = IFM_ETHER; bmsr = PHY_READ(sc, BRGPHY_MII_BMSR) | PHY_READ(sc, BRGPHY_MII_BMSR); bmcr = PHY_READ(sc, BRGPHY_MII_BMCR); anar = PHY_READ(sc, BRGPHY_MII_ANAR); anlpar = PHY_READ(sc, BRGPHY_MII_ANLPAR); /* Loopback is enabled. */ if (bmcr & BRGPHY_BMCR_LOOP) { mii->mii_media_active |= IFM_LOOP; } /* Autoneg is still in progress. */ if ((bmcr & BRGPHY_BMCR_AUTOEN) && (bmsr & BRGPHY_BMSR_ACOMP) == 0 && (bsc->serdes_flags & BRGPHY_NOANWAIT) == 0) { /* Erg, still trying, I guess... */ mii->mii_media_active |= IFM_NONE; goto brgphy_status_exit; } /* Autoneg is enabled and complete, link should be up. */ if ((sc->mii_flags & MIIF_HAVEFIBER) == 0) { aux = PHY_READ(sc, BRGPHY_MII_AUXSTS); /* If copper link is up, get the negotiated speed/duplex. */ if (aux & BRGPHY_AUXSTS_LINK) { mii->mii_media_status |= IFM_ACTIVE; switch (aux & BRGPHY_AUXSTS_AN_RES) { case BRGPHY_RES_1000FD: mii->mii_media_active |= IFM_1000_T | IFM_FDX; break; case BRGPHY_RES_1000HD: mii->mii_media_active |= IFM_1000_T | IFM_HDX; break; case BRGPHY_RES_100FD: mii->mii_media_active |= IFM_100_TX | IFM_FDX; break; case BRGPHY_RES_100T4: mii->mii_media_active |= IFM_100_T4; break; case BRGPHY_RES_100HD: mii->mii_media_active |= IFM_100_TX | IFM_HDX; break; case BRGPHY_RES_10FD: mii->mii_media_active |= IFM_10_T | IFM_FDX; break; case BRGPHY_RES_10HD: mii->mii_media_active |= IFM_10_T | IFM_HDX; break; default: mii->mii_media_active |= IFM_NONE; break; } } } else { /* If serdes link is up, get the negotiated speed/duplex. */ if (bmsr & BRGPHY_BMSR_LINK) { mii->mii_media_status |= IFM_ACTIVE; } /* Check the link speed/duplex based on the PHY type. */ if (bsc->serdes_flags & BRGPHY_5706S) { mii->mii_media_active |= IFM_1000_SX; /* If autoneg enabled, read negotiated duplex settings */ if (bmcr & BRGPHY_BMCR_AUTOEN) { val = PHY_READ(sc, BRGPHY_SERDES_ANAR) & PHY_READ(sc, BRGPHY_SERDES_ANLPAR); if (val & BRGPHY_SERDES_ANAR_FDX) mii->mii_media_active |= IFM_FDX; else mii->mii_media_active |= IFM_HDX; } } else if (bsc->serdes_flags & BRGPHY_5708S) { PHY_WRITE(sc, BRGPHY_5708S_BLOCK_ADDR, BRGPHY_5708S_DIG_PG0); xstat = PHY_READ(sc, BRGPHY_5708S_PG0_1000X_STAT1); + /* Check for MRBE auto-negotiated speed results. */ switch (xstat & BRGPHY_5708S_PG0_1000X_STAT1_SPEED_MASK) { case BRGPHY_5708S_PG0_1000X_STAT1_SPEED_10: mii->mii_media_active |= IFM_10_FL; break; case BRGPHY_5708S_PG0_1000X_STAT1_SPEED_100: mii->mii_media_active |= IFM_100_FX; break; case BRGPHY_5708S_PG0_1000X_STAT1_SPEED_1G: mii->mii_media_active |= IFM_1000_SX; break; case BRGPHY_5708S_PG0_1000X_STAT1_SPEED_25G: mii->mii_media_active |= IFM_2500_SX; break; } + /* Check for MRBE auto-negotiated duplex results. */ if (xstat & BRGPHY_5708S_PG0_1000X_STAT1_FDX) mii->mii_media_active |= IFM_FDX; else mii->mii_media_active |= IFM_HDX; - } + + } else if (bsc->serdes_flags & BRGPHY_5709S) { + + /* Select GP Status Block of the AN MMD, get autoneg results. */ + PHY_WRITE(sc, BRGPHY_BLOCK_ADDR, BRGPHY_BLOCK_ADDR_GP_STATUS); + xstat = PHY_READ(sc, BRGPHY_GP_STATUS_TOP_ANEG_STATUS); + + /* Restore IEEE0 block (assumed in all brgphy(4) code). */ + PHY_WRITE(sc, BRGPHY_BLOCK_ADDR, BRGPHY_BLOCK_ADDR_COMBO_IEEE0); + + /* Check for MRBE auto-negotiated speed results. */ + switch (xstat & BRGPHY_GP_STATUS_TOP_ANEG_SPEED_MASK) { + case BRGPHY_GP_STATUS_TOP_ANEG_SPEED_10: + mii->mii_media_active |= IFM_10_FL; break; + case BRGPHY_GP_STATUS_TOP_ANEG_SPEED_100: + mii->mii_media_active |= IFM_100_FX; break; + case BRGPHY_GP_STATUS_TOP_ANEG_SPEED_1G: + mii->mii_media_active |= IFM_1000_SX; break; + case BRGPHY_GP_STATUS_TOP_ANEG_SPEED_25G: + mii->mii_media_active |= IFM_2500_SX; break; + } + + /* Check for MRBE auto-negotiated duplex results. */ + if (xstat & BRGPHY_GP_STATUS_TOP_ANEG_FDX) + mii->mii_media_active |= IFM_FDX; + else + mii->mii_media_active |= IFM_HDX; + } + } #if 0 /* Todo: Change bge/bce to use these settings. */ /* Fetch flow control settings from the PHY */ if ((sc->mii_flags & MIIF_HAVEFIBER) == 0) { /* Set FLAG0 is RX is enabled and FLAG1 if TX is enabled */ if ((anar & BRGPHY_ANAR_PC) && (anlpar & BRGPHY_ANLPAR_PC)) { mii->mii_media_active |= IFM_FLAG0 | IFM_FLAG1; } else if (!(anar & BRGPHY_ANAR_PC) && (anlpar & BRGPHY_ANAR_ASP) && (anlpar & BRPHY_ANLPAR_PC) && (anlpar & BRGPHY_ANLPAR_ASP)) { mii->mii_media_active |= IFM_FLAG1; } else if ((anar & BRGPHY_ANAR_PC) && (anar & BRGPHY_ANAR_ASP) && !(anlpar & BRGPHY_ANLPAR_PC) && (anlpar & BRGPHY_ANLPAR_ASP)) { mii->mii_media_active |= IFM_FLAG0; } } /* Todo: Add support for fiber settings too. */ #endif brgphy_status_exit: return; } static void brgphy_mii_phy_auto(struct mii_softc *sc) { struct brgphy_softc *bsc = (struct brgphy_softc *)sc; int ktcr = 0; brgphy_reset(sc); /* Enable flow control in the advertisement register. */ if ((sc->mii_flags & MIIF_HAVEFIBER) == 0) { /* Pause capability advertisement (pause capable & asymmetric) */ PHY_WRITE(sc, BRGPHY_MII_ANAR, BMSR_MEDIA_TO_ANAR(sc->mii_capabilities) | ANAR_CSMA | BRGPHY_ANAR_ASP | BRGPHY_ANAR_PC); } else { PHY_WRITE(sc, BRGPHY_SERDES_ANAR, BRGPHY_SERDES_ANAR_FDX | BRGPHY_SERDES_ANAR_HDX | BRGPHY_SERDES_ANAR_BOTH_PAUSE); } /* Enable speed in the 1000baseT control register */ ktcr = BRGPHY_1000CTL_AFD | BRGPHY_1000CTL_AHD; if (bsc->mii_model == MII_MODEL_xxBROADCOM_BCM5701) ktcr |= BRGPHY_1000CTL_MSE | BRGPHY_1000CTL_MSC; PHY_WRITE(sc, BRGPHY_MII_1000CTL, ktcr); ktcr = PHY_READ(sc, BRGPHY_MII_1000CTL); /* Start autonegotiation */ PHY_WRITE(sc, BRGPHY_MII_BMCR,BRGPHY_BMCR_AUTOEN | BRGPHY_BMCR_STARTNEG); PHY_WRITE(sc, BRGPHY_MII_IMR, 0xFF00); } /* Enable loopback to force the link down. */ static void brgphy_enable_loopback(struct mii_softc *sc) { int i; PHY_WRITE(sc, BRGPHY_MII_BMCR, BRGPHY_BMCR_LOOP); for (i = 0; i < 15000; i++) { if (!(PHY_READ(sc, BRGPHY_MII_BMSR) & BRGPHY_BMSR_LINK)) break; DELAY(10); } } /* Turn off tap power management on 5401. */ static void bcm5401_load_dspcode(struct mii_softc *sc) { static const struct { int reg; uint16_t val; } dspcode[] = { { BRGPHY_MII_AUXCTL, 0x0c20 }, { BRGPHY_MII_DSP_ADDR_REG, 0x0012 }, { BRGPHY_MII_DSP_RW_PORT, 0x1804 }, { BRGPHY_MII_DSP_ADDR_REG, 0x0013 }, { BRGPHY_MII_DSP_RW_PORT, 0x1204 }, { BRGPHY_MII_DSP_ADDR_REG, 0x8006 }, { BRGPHY_MII_DSP_RW_PORT, 0x0132 }, { BRGPHY_MII_DSP_ADDR_REG, 0x8006 }, { BRGPHY_MII_DSP_RW_PORT, 0x0232 }, { BRGPHY_MII_DSP_ADDR_REG, 0x201f }, { BRGPHY_MII_DSP_RW_PORT, 0x0a20 }, { 0, 0 }, }; int i; for (i = 0; dspcode[i].reg != 0; i++) PHY_WRITE(sc, dspcode[i].reg, dspcode[i].val); DELAY(40); } static void bcm5411_load_dspcode(struct mii_softc *sc) { static const struct { int reg; uint16_t val; } dspcode[] = { { 0x1c, 0x8c23 }, { 0x1c, 0x8ca3 }, { 0x1c, 0x8c23 }, { 0, 0 }, }; int i; for (i = 0; dspcode[i].reg != 0; i++) PHY_WRITE(sc, dspcode[i].reg, dspcode[i].val); } void bcm54k2_load_dspcode(struct mii_softc *sc) { static const struct { int reg; uint16_t val; } dspcode[] = { { 4, 0x01e1 }, { 9, 0x0300 }, { 0, 0 }, }; int i; for (i = 0; dspcode[i].reg != 0; i++) PHY_WRITE(sc, dspcode[i].reg, dspcode[i].val); } static void brgphy_fixup_5704_a0_bug(struct mii_softc *sc) { static const struct { int reg; uint16_t val; } dspcode[] = { { 0x1c, 0x8d68 }, { 0x1c, 0x8d68 }, { 0, 0 }, }; int i; for (i = 0; dspcode[i].reg != 0; i++) PHY_WRITE(sc, dspcode[i].reg, dspcode[i].val); } static void brgphy_fixup_adc_bug(struct mii_softc *sc) { static const struct { int reg; uint16_t val; } dspcode[] = { { BRGPHY_MII_AUXCTL, 0x0c00 }, { BRGPHY_MII_DSP_ADDR_REG, 0x201f }, { BRGPHY_MII_DSP_RW_PORT, 0x2aaa }, { 0, 0 }, }; int i; for (i = 0; dspcode[i].reg != 0; i++) PHY_WRITE(sc, dspcode[i].reg, dspcode[i].val); } static void brgphy_fixup_adjust_trim(struct mii_softc *sc) { static const struct { int reg; uint16_t val; } dspcode[] = { { BRGPHY_MII_AUXCTL, 0x0c00 }, { BRGPHY_MII_DSP_ADDR_REG, 0x000a }, { BRGPHY_MII_DSP_RW_PORT, 0x110b }, { BRGPHY_MII_TEST1, 0x0014 }, { BRGPHY_MII_AUXCTL, 0x0400 }, { 0, 0 }, }; int i; for (i = 0; dspcode[i].reg != 0; i++) PHY_WRITE(sc, dspcode[i].reg, dspcode[i].val); } static void brgphy_fixup_ber_bug(struct mii_softc *sc) { static const struct { int reg; uint16_t val; } dspcode[] = { { BRGPHY_MII_AUXCTL, 0x0c00 }, { BRGPHY_MII_DSP_ADDR_REG, 0x000a }, { BRGPHY_MII_DSP_RW_PORT, 0x310b }, { BRGPHY_MII_DSP_ADDR_REG, 0x201f }, { BRGPHY_MII_DSP_RW_PORT, 0x9506 }, { BRGPHY_MII_DSP_ADDR_REG, 0x401f }, { BRGPHY_MII_DSP_RW_PORT, 0x14e2 }, { BRGPHY_MII_AUXCTL, 0x0400 }, { 0, 0 }, }; int i; for (i = 0; dspcode[i].reg != 0; i++) PHY_WRITE(sc, dspcode[i].reg, dspcode[i].val); } static void brgphy_fixup_crc_bug(struct mii_softc *sc) { static const struct { int reg; uint16_t val; } dspcode[] = { { BRGPHY_MII_DSP_RW_PORT, 0x0a75 }, { 0x1c, 0x8c68 }, { 0x1c, 0x8d68 }, { 0x1c, 0x8c68 }, { 0, 0 }, }; int i; for (i = 0; dspcode[i].reg != 0; i++) PHY_WRITE(sc, dspcode[i].reg, dspcode[i].val); } static void brgphy_fixup_jitter_bug(struct mii_softc *sc) { static const struct { int reg; uint16_t val; } dspcode[] = { { BRGPHY_MII_AUXCTL, 0x0c00 }, { BRGPHY_MII_DSP_ADDR_REG, 0x000a }, { BRGPHY_MII_DSP_RW_PORT, 0x010b }, { BRGPHY_MII_AUXCTL, 0x0400 }, { 0, 0 }, }; int i; for (i = 0; dspcode[i].reg != 0; i++) PHY_WRITE(sc, dspcode[i].reg, dspcode[i].val); } static void brgphy_fixup_disable_early_dac(struct mii_softc *sc) { uint32_t val; PHY_WRITE(sc, BRGPHY_MII_DSP_ADDR_REG, 0x0f08); val = PHY_READ(sc, BRGPHY_MII_DSP_RW_PORT); val &= ~(1 << 8); PHY_WRITE(sc, BRGPHY_MII_DSP_RW_PORT, val); } static void brgphy_ethernet_wirespeed(struct mii_softc *sc) { uint32_t val; /* Enable Ethernet@WireSpeed. */ PHY_WRITE(sc, BRGPHY_MII_AUXCTL, 0x7007); val = PHY_READ(sc, BRGPHY_MII_AUXCTL); PHY_WRITE(sc, BRGPHY_MII_AUXCTL, val | (1 << 15) | (1 << 4)); } 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) { /* BCM5401 PHY cannot read-modify-write. */ PHY_WRITE(sc, BRGPHY_MII_AUXCTL, 0x4c20); } else { PHY_WRITE(sc, BRGPHY_MII_AUXCTL, 0x7); val = PHY_READ(sc, BRGPHY_MII_AUXCTL); PHY_WRITE(sc, BRGPHY_MII_AUXCTL, val | BRGPHY_AUXCTL_LONG_PKT); } val = PHY_READ(sc, BRGPHY_MII_PHY_EXTCTL); PHY_WRITE(sc, BRGPHY_MII_PHY_EXTCTL, val | BRGPHY_PHY_EXTCTL_HIGH_LA); } else { PHY_WRITE(sc, BRGPHY_MII_AUXCTL, 0x7); val = PHY_READ(sc, BRGPHY_MII_AUXCTL); PHY_WRITE(sc, BRGPHY_MII_AUXCTL, val & ~(BRGPHY_AUXCTL_LONG_PKT | 0x7)); val = PHY_READ(sc, BRGPHY_MII_PHY_EXTCTL); PHY_WRITE(sc, BRGPHY_MII_PHY_EXTCTL, val & ~BRGPHY_PHY_EXTCTL_HIGH_LA); } } 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; + int val; /* Perform a standard PHY reset. */ mii_phy_reset(sc); /* Handle any PHY specific procedures following the reset. */ switch (bsc->mii_oui) { case MII_OUI_BROADCOM: break; case MII_OUI_xxBROADCOM: switch (bsc->mii_model) { case MII_MODEL_xxBROADCOM_BCM5400: bcm5401_load_dspcode(sc); break; case MII_MODEL_xxBROADCOM_BCM5401: if (bsc->mii_rev == 1 || bsc->mii_rev == 3) bcm5401_load_dspcode(sc); break; case MII_MODEL_xxBROADCOM_BCM5411: bcm5411_load_dspcode(sc); break; case MII_MODEL_xxBROADCOM_BCM54K2: bcm54k2_load_dspcode(sc); break; } break; case MII_OUI_xxBROADCOM_ALT1: break; } 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; } /* Handle any bge (NetXtreme/NetLink) workarounds. */ if (bge_sc) { /* Fix up various bugs */ if (bge_sc->bge_flags & BGE_FLAG_5704_A0_BUG) brgphy_fixup_5704_a0_bug(sc); if (bge_sc->bge_flags & BGE_FLAG_ADC_BUG) brgphy_fixup_adc_bug(sc); if (bge_sc->bge_flags & BGE_FLAG_ADJUST_TRIM) brgphy_fixup_adjust_trim(sc); if (bge_sc->bge_flags & BGE_FLAG_BER_BUG) brgphy_fixup_ber_bug(sc); if (bge_sc->bge_flags & BGE_FLAG_CRC_BUG) brgphy_fixup_crc_bug(sc); if (bge_sc->bge_flags & BGE_FLAG_JITTER_BUG) brgphy_fixup_jitter_bug(sc); brgphy_jumbo_settings(sc, ifp->if_mtu); if (bge_sc->bge_flags & BGE_FLAG_WIRESPEED) brgphy_ethernet_wirespeed(sc); /* Enable Link LED on Dell boxes */ if (bge_sc->bge_flags & BGE_FLAG_NO_3LED) { PHY_WRITE(sc, BRGPHY_MII_PHY_EXTCTL, PHY_READ(sc, BRGPHY_MII_PHY_EXTCTL) & ~BRGPHY_PHY_EXTCTL_3_LED); } /* Adjust output voltage (From Linux driver) */ if (bge_sc->bge_asicrev == BGE_ASICREV_BCM5906) PHY_WRITE(sc, BRGPHY_MII_EPHY_PTEST, 0x12); /* Handle any bce (NetXtreme II) workarounds. */ } else if (bce_sc) { if (BCE_CHIP_NUM(bce_sc) == BCE_CHIP_NUM_5708 && (bce_sc->bce_phy_flags & BCE_PHY_SERDES_FLAG)) { /* Store autoneg capabilities/results in digital block (Page 0) */ PHY_WRITE(sc, BRGPHY_5708S_BLOCK_ADDR, BRGPHY_5708S_DIG3_PG2); PHY_WRITE(sc, BRGPHY_5708S_PG2_DIGCTL_3_0, BRGPHY_5708S_PG2_DIGCTL_3_0_USE_IEEE); PHY_WRITE(sc, BRGPHY_5708S_BLOCK_ADDR, BRGPHY_5708S_DIG_PG0); /* Enable fiber mode and autodetection */ PHY_WRITE(sc, BRGPHY_5708S_PG0_1000X_CTL1, PHY_READ(sc, BRGPHY_5708S_PG0_1000X_CTL1) | BRGPHY_5708S_PG0_1000X_CTL1_AUTODET_EN | BRGPHY_5708S_PG0_1000X_CTL1_FIBER_MODE); /* Enable parallel detection */ PHY_WRITE(sc, BRGPHY_5708S_PG0_1000X_CTL2, PHY_READ(sc, BRGPHY_5708S_PG0_1000X_CTL2) | BRGPHY_5708S_PG0_1000X_CTL2_PAR_DET_EN); /* Advertise 2.5G support through next page during autoneg */ if (bce_sc->bce_phy_flags & BCE_PHY_2_5G_CAPABLE_FLAG) PHY_WRITE(sc, BRGPHY_5708S_ANEG_NXT_PG_XMIT1, PHY_READ(sc, BRGPHY_5708S_ANEG_NXT_PG_XMIT1) | BRGPHY_5708S_ANEG_NXT_PG_XMIT1_25G); /* Increase TX signal amplitude */ if ((BCE_CHIP_ID(bce_sc) == BCE_CHIP_ID_5708_A0) || (BCE_CHIP_ID(bce_sc) == BCE_CHIP_ID_5708_B0) || (BCE_CHIP_ID(bce_sc) == BCE_CHIP_ID_5708_B1)) { PHY_WRITE(sc, BRGPHY_5708S_BLOCK_ADDR, BRGPHY_5708S_TX_MISC_PG5); PHY_WRITE(sc, BRGPHY_5708S_PG5_TXACTL1, PHY_READ(sc, BRGPHY_5708S_PG5_TXACTL1) & ~0x30); PHY_WRITE(sc, BRGPHY_5708S_BLOCK_ADDR, BRGPHY_5708S_DIG_PG0); } /* Backplanes use special driver/pre-driver/pre-emphasis values. */ if ((bce_sc->bce_shared_hw_cfg & BCE_SHARED_HW_CFG_PHY_BACKPLANE) && (bce_sc->bce_port_hw_cfg & BCE_PORT_HW_CFG_CFG_TXCTL3_MASK)) { PHY_WRITE(sc, BRGPHY_5708S_BLOCK_ADDR, BRGPHY_5708S_TX_MISC_PG5); PHY_WRITE(sc, BRGPHY_5708S_PG5_TXACTL3, bce_sc->bce_port_hw_cfg & BCE_PORT_HW_CFG_CFG_TXCTL3_MASK); PHY_WRITE(sc, BRGPHY_5708S_BLOCK_ADDR, BRGPHY_5708S_DIG_PG0); } - } else if (BCE_CHIP_NUM(bce_sc) == BCE_CHIP_NUM_5709) { + } else if (BCE_CHIP_NUM(bce_sc) == BCE_CHIP_NUM_5709 && + (bce_sc->bce_phy_flags & BCE_PHY_SERDES_FLAG)) { + + /* Select the SerDes Digital block of the AN MMD. */ + PHY_WRITE(sc, BRGPHY_BLOCK_ADDR, BRGPHY_BLOCK_ADDR_SERDES_DIG); + val = PHY_READ(sc, BRGPHY_SERDES_DIG_1000X_CTL1); + val &= ~BRGPHY_SD_DIG_1000X_CTL1_AUTODET; + val |= BRGPHY_SD_DIG_1000X_CTL1_FIBER; + PHY_WRITE(sc, BRGPHY_SERDES_DIG_1000X_CTL1, val); + + /* Select the Over 1G block of the AN MMD. */ + PHY_WRITE(sc, BRGPHY_BLOCK_ADDR, BRGPHY_BLOCK_ADDR_OVER_1G); + + /* Enable autoneg "Next Page" to advertise 2.5G support. */ + val = PHY_READ(sc, BRGPHY_OVER_1G_UNFORMAT_PG1); + if (bce_sc->bce_phy_flags & BCE_PHY_2_5G_CAPABLE_FLAG) + val |= BRGPHY_5708S_ANEG_NXT_PG_XMIT1_25G; + else + val &= ~BRGPHY_5708S_ANEG_NXT_PG_XMIT1_25G; + PHY_WRITE(sc, BRGPHY_OVER_1G_UNFORMAT_PG1, val); + + /* Select the Multi-Rate Backplane Ethernet block of the AN MMD. */ + PHY_WRITE(sc, BRGPHY_BLOCK_ADDR, BRGPHY_BLOCK_ADDR_MRBE); + + /* Enable MRBE speed autoneg. */ + val = PHY_READ(sc, BRGPHY_MRBE_MSG_PG5_NP); + val |= BRGPHY_MRBE_MSG_PG5_NP_MBRE | + BRGPHY_MRBE_MSG_PG5_NP_T2; + PHY_WRITE(sc, BRGPHY_MRBE_MSG_PG5_NP, val); + + /* Select the Clause 73 User B0 block of the AN MMD. */ + PHY_WRITE(sc, BRGPHY_BLOCK_ADDR, BRGPHY_BLOCK_ADDR_CL73_USER_B0); + + /* Enable MRBE speed autoneg. */ + PHY_WRITE(sc, BRGPHY_CL73_USER_B0_MBRE_CTL1, + BRGPHY_CL73_USER_B0_MBRE_CTL1_NP_AFT_BP | + BRGPHY_CL73_USER_B0_MBRE_CTL1_STA_MGR | + BRGPHY_CL73_USER_B0_MBRE_CTL1_ANEG); + + /* Restore IEEE0 block (assumed in all brgphy(4) code). */ + PHY_WRITE(sc, BRGPHY_BLOCK_ADDR, BRGPHY_BLOCK_ADDR_COMBO_IEEE0); + + } else if (BCE_CHIP_NUM(bce_sc) == BCE_CHIP_NUM_5709) { if ((BCE_CHIP_REV(bce_sc) == BCE_CHIP_REV_Ax) || (BCE_CHIP_REV(bce_sc) == BCE_CHIP_REV_Bx)) brgphy_fixup_disable_early_dac(sc); brgphy_jumbo_settings(sc, ifp->if_mtu); brgphy_ethernet_wirespeed(sc); } else { brgphy_fixup_ber_bug(sc); brgphy_jumbo_settings(sc, ifp->if_mtu); brgphy_ethernet_wirespeed(sc); } } } Index: head/sys/dev/mii/brgphyreg.h =================================================================== --- head/sys/dev/mii/brgphyreg.h (revision 205298) +++ head/sys/dev/mii/brgphyreg.h (revision 205299) @@ -1,365 +1,420 @@ /*- * Copyright (c) 2000 * Bill Paul . All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by Bill Paul. * 4. Neither the name of the author nor the names of any co-contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. * * $FreeBSD$ */ #ifndef _DEV_MII_BRGPHYREG_H_ #define _DEV_MII_BRGPHYREG_H_ /* * Broadcom BCM5400 registers */ #define BRGPHY_MII_BMCR 0x00 #define BRGPHY_BMCR_RESET 0x8000 #define BRGPHY_BMCR_LOOP 0x4000 #define BRGPHY_BMCR_SPD0 0x2000 /* Speed select, lower bit */ #define BRGPHY_BMCR_AUTOEN 0x1000 /* Autoneg enabled */ #define BRGPHY_BMCR_PDOWN 0x0800 /* Power down */ #define BRGPHY_BMCR_ISO 0x0400 /* Isolate */ #define BRGPHY_BMCR_STARTNEG 0x0200 /* Restart autoneg */ #define BRGPHY_BMCR_FDX 0x0100 /* Duplex mode */ #define BRGPHY_BMCR_CTEST 0x0080 /* Collision test enable */ #define BRGPHY_BMCR_SPD1 0x0040 /* Speed select, upper bit */ #define BRGPHY_S1000 BRGPHY_BMCR_SPD1 /* 1000mbps */ #define BRGPHY_S100 BRGPHY_BMCR_SPD0 /* 100mpbs */ #define BRGPHY_S10 0 /* 10mbps */ #define BRGPHY_MII_BMSR 0x01 #define BRGPHY_BMSR_EXTSTS 0x0100 /* Extended status present */ #define BRGPHY_BMSR_PRESUB 0x0040 /* Preamble surpression */ #define BRGPHY_BMSR_ACOMP 0x0020 /* Autoneg complete */ #define BRGPHY_BMSR_RFAULT 0x0010 /* Remote fault condition occured */ #define BRGPHY_BMSR_ANEG 0x0008 /* Autoneg capable */ #define BRGPHY_BMSR_LINK 0x0004 /* Link status */ #define BRGPHY_BMSR_JABBER 0x0002 /* Jabber detected */ #define BRGPHY_BMSR_EXT 0x0001 /* Extended capability */ #define BRGPHY_MII_ANAR 0x04 #define BRGPHY_ANAR_NP 0x8000 /* Next page */ #define BRGPHY_ANAR_RF 0x2000 /* Remote fault */ #define BRGPHY_ANAR_ASP 0x0800 /* Asymmetric Pause */ #define BRGPHY_ANAR_PC 0x0400 /* Pause capable */ #define BRGPHY_ANAR_SEL 0x001F /* Selector field, 00001=Ethernet */ #define BRGPHY_MII_ANLPAR 0x05 #define BRGPHY_ANLPAR_NP 0x8000 /* Next page */ #define BRGPHY_ANLPAR_RF 0x2000 /* Remote fault */ #define BRGPHY_ANLPAR_ASP 0x0800 /* Asymmetric Pause */ #define BRGPHY_ANLPAR_PC 0x0400 /* Pause capable */ #define BRGPHY_ANLPAR_SEL 0x001F /* Selector field, 00001=Ethernet */ #define BRGPHY_SEL_TYPE 0x0001 /* Ethernet */ #define BRGPHY_MII_ANER 0x06 #define BRGPHY_ANER_PDF 0x0010 /* Parallel detection fault */ #define BRGPHY_ANER_LPNP 0x0008 /* Link partner can next page */ #define BRGPHY_ANER_NP 0x0004 /* Local PHY can next page */ #define BRGPHY_ANER_RX 0x0002 /* Next page received */ #define BRGPHY_ANER_LPAN 0x0001 /* Link partner autoneg capable */ #define BRGPHY_MII_NEXTP 0x07 /* Next page */ #define BRGPHY_MII_NEXTP_LP 0x08 /* Next page of link partner */ #define BRGPHY_MII_1000CTL 0x09 /* 1000baseT control */ #define BRGPHY_1000CTL_TST 0xE000 /* Test modes */ #define BRGPHY_1000CTL_MSE 0x1000 /* Master/Slave enable */ #define BRGPHY_1000CTL_MSC 0x0800 /* Master/Slave configuration */ #define BRGPHY_1000CTL_RD 0x0400 /* Repeater/DTE */ #define BRGPHY_1000CTL_AFD 0x0200 /* Advertise full duplex */ #define BRGPHY_1000CTL_AHD 0x0100 /* Advertise half duplex */ #define BRGPHY_MII_1000STS 0x0A /* 1000baseT status */ #define BRGPHY_1000STS_MSF 0x8000 /* Master/slave fault */ #define BRGPHY_1000STS_MSR 0x4000 /* Master/slave result */ #define BRGPHY_1000STS_LRS 0x2000 /* Local receiver status */ #define BRGPHY_1000STS_RRS 0x1000 /* Remote receiver status */ #define BRGPHY_1000STS_LPFD 0x0800 /* Link partner can FD */ #define BRGPHY_1000STS_LPHD 0x0400 /* Link partner can HD */ #define BRGPHY_1000STS_IEC 0x00FF /* Idle error count */ #define BRGPHY_MII_EXTSTS 0x0F /* Extended status */ #define BRGPHY_EXTSTS_X_FD_CAP 0x8000 /* 1000base-X FD capable */ #define BRGPHY_EXTSTS_X_HD_CAP 0x4000 /* 1000base-X HD capable */ #define BRGPHY_EXTSTS_T_FD_CAP 0x2000 /* 1000base-T FD capable */ #define BRGPHY_EXTSTS_T_HD_CAP 0x1000 /* 1000base-T HD capable */ #define BRGPHY_MII_PHY_EXTCTL 0x10 /* PHY extended control */ #define BRGPHY_PHY_EXTCTL_MAC_PHY 0x8000 /* 10BIT/GMI-interface */ #define BRGPHY_PHY_EXTCTL_DIS_CROSS 0x4000 /* Disable MDI crossover */ #define BRGPHY_PHY_EXTCTL_TX_DIS 0x2000 /* TX output disabled */ #define BRGPHY_PHY_EXTCTL_INT_DIS 0x1000 /* Interrupts disabled */ #define BRGPHY_PHY_EXTCTL_F_INT 0x0800 /* Force interrupt */ #define BRGPHY_PHY_EXTCTL_BY_45 0x0400 /* Bypass 4B5B-Decoder */ #define BRGPHY_PHY_EXTCTL_BY_SCR 0x0200 /* Bypass scrambler */ #define BRGPHY_PHY_EXTCTL_BY_MLT3 0x0100 /* Bypass MLT3 encoder */ #define BRGPHY_PHY_EXTCTL_BY_RXA 0x0080 /* Bypass RX alignment */ #define BRGPHY_PHY_EXTCTL_RES_SCR 0x0040 /* Reset scrambler */ #define BRGPHY_PHY_EXTCTL_EN_LTR 0x0020 /* Enable LED traffic mode */ #define BRGPHY_PHY_EXTCTL_LED_ON 0x0010 /* Force LEDs on */ #define BRGPHY_PHY_EXTCTL_LED_OFF 0x0008 /* Force LEDs off */ #define BRGPHY_PHY_EXTCTL_EX_IPG 0x0004 /* Extended TX IPG mode */ #define BRGPHY_PHY_EXTCTL_3_LED 0x0002 /* Three link LED mode */ #define BRGPHY_PHY_EXTCTL_HIGH_LA 0x0001 /* GMII Fifo Elasticy (?) */ #define BRGPHY_MII_PHY_EXTSTS 0x11 /* PHY extended status */ #define BRGPHY_PHY_EXTSTS_CROSS_STAT 0x2000 /* MDI crossover status */ #define BRGPHY_PHY_EXTSTS_INT_STAT 0x1000 /* Interrupt status */ #define BRGPHY_PHY_EXTSTS_RRS 0x0800 /* Remote receiver status */ #define BRGPHY_PHY_EXTSTS_LRS 0x0400 /* Local receiver status */ #define BRGPHY_PHY_EXTSTS_LOCKED 0x0200 /* Locked */ #define BRGPHY_PHY_EXTSTS_LS 0x0100 /* Link status */ #define BRGPHY_PHY_EXTSTS_RF 0x0080 /* Remove fault */ #define BRGPHY_PHY_EXTSTS_CE_ER 0x0040 /* Carrier ext error */ #define BRGPHY_PHY_EXTSTS_BAD_SSD 0x0020 /* Bad SSD */ #define BRGPHY_PHY_EXTSTS_BAD_ESD 0x0010 /* Bad ESS */ #define BRGPHY_PHY_EXTSTS_RX_ER 0x0008 /* RX error */ #define BRGPHY_PHY_EXTSTS_TX_ER 0x0004 /* TX error */ #define BRGPHY_PHY_EXTSTS_LOCK_ER 0x0002 /* Lock error */ #define BRGPHY_PHY_EXTSTS_MLT3_ER 0x0001 /* MLT3 code error */ #define BRGPHY_MII_RXERRCNT 0x12 /* RX error counter */ #define BRGPHY_MII_FCERRCNT 0x13 /* False carrier sense counter */ #define BGRPHY_FCERRCNT 0x00FF /* False carrier counter */ #define BRGPHY_MII_RXNOCNT 0x14 /* RX not OK counter */ #define BRGPHY_RXNOCNT_LOCAL 0xFF00 /* Local RX not OK counter */ #define BRGPHY_RXNOCNT_REMOTE 0x00FF /* Local RX not OK counter */ #define BRGPHY_MII_DSP_RW_PORT 0x15 /* DSP coefficient r/w port */ #define BRGPHY_MII_DSP_ADDR_REG 0x17 /* DSP coefficient addr register */ #define BRGPHY_MII_EPHY_PTEST 0x17 /* 5906 PHY register */ #define BRGPHY_DSP_TAP_NUMBER_MASK 0x00 #define BRGPHY_DSP_AGC_A 0x00 #define BRGPHY_DSP_AGC_B 0x01 #define BRGPHY_DSP_MSE_PAIR_STATUS 0x02 #define BRGPHY_DSP_SOFT_DECISION 0x03 #define BRGPHY_DSP_PHASE_REG 0x04 #define BRGPHY_DSP_SKEW 0x05 #define BRGPHY_DSP_POWER_SAVER_UPPER_BOUND 0x06 #define BRGPHY_DSP_POWER_SAVER_LOWER_BOUND 0x07 #define BRGPHY_DSP_LAST_ECHO 0x08 #define BRGPHY_DSP_FREQUENCY 0x09 #define BRGPHY_DSP_PLL_BANDWIDTH 0x0A #define BRGPHY_DSP_PLL_PHASE_OFFSET 0x0B #define BRGPHYDSP_FILTER_DCOFFSET 0x0C00 #define BRGPHY_DSP_FILTER_FEXT3 0x0B00 #define BRGPHY_DSP_FILTER_FEXT2 0x0A00 #define BRGPHY_DSP_FILTER_FEXT1 0x0900 #define BRGPHY_DSP_FILTER_FEXT0 0x0800 #define BRGPHY_DSP_FILTER_NEXT3 0x0700 #define BRGPHY_DSP_FILTER_NEXT2 0x0600 #define BRGPHY_DSP_FILTER_NEXT1 0x0500 #define BRGPHY_DSP_FILTER_NEXT0 0x0400 #define BRGPHY_DSP_FILTER_ECHO 0x0300 #define BRGPHY_DSP_FILTER_DFE 0x0200 #define BRGPHY_DSP_FILTER_FFE 0x0100 #define BRGPHY_DSP_CONTROL_ALL_FILTERS 0x1000 #define BRGPHY_DSP_SEL_CH_0 0x0000 #define BRGPHY_DSP_SEL_CH_1 0x2000 #define BRGPHY_DSP_SEL_CH_2 0x4000 #define BRGPHY_DSP_SEL_CH_3 0x6000 #define BRGPHY_MII_AUXCTL 0x18 /* AUX control */ #define BRGPHY_AUXCTL_LOW_SQ 0x8000 /* Low squelch */ #define BRGPHY_AUXCTL_LONG_PKT 0x4000 /* RX long packets */ #define BRGPHY_AUXCTL_ER_CTL 0x3000 /* Edgerate control */ #define BRGPHY_AUXCTL_TX_TST 0x0400 /* TX test, always 1 */ #define BRGPHY_AUXCTL_DIS_PRF 0x0080 /* dis part resp filter */ #define BRGPHY_AUXCTL_DIAG_MODE 0x0004 /* Diagnostic mode */ #define BRGPHY_MII_AUXSTS 0x19 /* AUX status */ #define BRGPHY_AUXSTS_ACOMP 0x8000 /* Autoneg complete */ #define BRGPHY_AUXSTS_AN_ACK 0x4000 /* Autoneg complete ack */ #define BRGPHY_AUXSTS_AN_ACK_D 0x2000 /* Autoneg complete ack detect */ #define BRGPHY_AUXSTS_AN_NPW 0x1000 /* Autoneg next page wait */ #define BRGPHY_AUXSTS_AN_RES 0x0700 /* Autoneg HCD */ #define BRGPHY_AUXSTS_PDF 0x0080 /* Parallel detect. fault */ #define BRGPHY_AUXSTS_RF 0x0040 /* Remote fault */ #define BRGPHY_AUXSTS_ANP_R 0x0020 /* Autoneg page received */ #define BRGPHY_AUXSTS_LP_ANAB 0x0010 /* Link partner autoneg ability */ #define BRGPHY_AUXSTS_LP_NPAB 0x0008 /* Link partner next page ability */ #define BRGPHY_AUXSTS_LINK 0x0004 /* Link status */ #define BRGPHY_AUXSTS_PRR 0x0002 /* Pause resolution-RX */ #define BRGPHY_AUXSTS_PRT 0x0001 /* Pause resolution-TX */ #define BRGPHY_RES_1000FD 0x0700 /* 1000baseT full duplex */ #define BRGPHY_RES_1000HD 0x0600 /* 1000baseT half duplex */ #define BRGPHY_RES_100FD 0x0500 /* 100baseT full duplex */ #define BRGPHY_RES_100T4 0x0400 /* 100baseT4 */ #define BRGPHY_RES_100HD 0x0300 /* 100baseT half duplex */ #define BRGPHY_RES_10FD 0x0200 /* 10baseT full duplex */ #define BRGPHY_RES_10HD 0x0100 /* 10baseT half duplex */ #define BRGPHY_MII_ISR 0x1A /* Interrupt status */ #define BRGPHY_ISR_PSERR 0x4000 /* Pair swap error */ #define BRGPHY_ISR_MDXI_SC 0x2000 /* MDIX Status Change */ #define BRGPHY_ISR_HCT 0x1000 /* Counter above 32K */ #define BRGPHY_ISR_LCT 0x0800 /* All counter below 128 */ #define BRGPHY_ISR_AN_PR 0x0400 /* Autoneg page received */ #define BRGPHY_ISR_NO_HDCL 0x0200 /* No HCD Link */ #define BRGPHY_ISR_NO_HDC 0x0100 /* No HCD */ #define BRGPHY_ISR_USHDC 0x0080 /* Negotiated Unsupported HCD */ #define BRGPHY_ISR_SCR_S_ERR 0x0040 /* Scrambler sync error */ #define BRGPHY_ISR_RRS_CHG 0x0020 /* Remote RX status change */ #define BRGPHY_ISR_LRS_CHG 0x0010 /* Local RX status change */ #define BRGPHY_ISR_DUP_CHG 0x0008 /* Duplex mode change */ #define BRGPHY_ISR_LSP_CHG 0x0004 /* Link speed changed */ #define BRGPHY_ISR_LNK_CHG 0x0002 /* Link status change */ #define BRGPHY_ISR_CRCERR 0x0001 /* CRC error */ #define BRGPHY_MII_IMR 0x1B /* Interrupt mask */ #define BRGPHY_IMR_PSERR 0x4000 /* Pair swap error */ #define BRGPHY_IMR_MDXI_SC 0x2000 /* MDIX Status Change */ #define BRGPHY_IMR_HCT 0x1000 /* Counter above 32K */ #define BRGPHY_IMR_LCT 0x0800 /* All counter below 128 */ #define BRGPHY_IMR_AN_PR 0x0400 /* Autoneg page received */ #define BRGPHY_IMR_NO_HDCL 0x0200 /* No HCD Link */ #define BRGPHY_IMR_NO_HDC 0x0100 /* No HCD */ #define BRGPHY_IMR_USHDC 0x0080 /* Negotiated Unsupported HCD */ #define BRGPHY_IMR_SCR_S_ERR 0x0040 /* Scrambler sync error */ #define BRGPHY_IMR_RRS_CHG 0x0020 /* Remote RX status change */ #define BRGPHY_IMR_LRS_CHG 0x0010 /* Local RX status change */ #define BRGPHY_IMR_DUP_CHG 0x0008 /* Duplex mode change */ #define BRGPHY_IMR_LSP_CHG 0x0004 /* Link speed changed */ #define BRGPHY_IMR_LNK_CHG 0x0002 /* Link status change */ #define BRGPHY_IMR_CRCERR 0x0001 /* CRC error */ /*******************************************************/ /* Begin: Shared SerDes PHY register definitions */ /*******************************************************/ /* SerDes autoneg is different from copper */ #define BRGPHY_SERDES_ANAR 0x04 #define BRGPHY_SERDES_ANAR_FDX 0x0020 #define BRGPHY_SERDES_ANAR_HDX 0x0040 #define BRGPHY_SERDES_ANAR_NO_PAUSE (0x0 << 7) #define BRGPHY_SERDES_ANAR_SYM_PAUSE (0x1 << 7) #define BRGPHY_SERDES_ANAR_ASYM_PAUSE (0x2 << 7) #define BRGPHY_SERDES_ANAR_BOTH_PAUSE (0x3 << 7) #define BRGPHY_SERDES_ANLPAR 0x05 #define BRGPHY_SERDES_ANLPAR_FDX 0x0020 #define BRGPHY_SERDES_ANLPAR_HDX 0x0040 #define BRGPHY_SERDES_ANLPAR_NO_PAUSE (0x0 << 7) #define BRGPHY_SERDES_ANLPAR_SYM_PAUSE (0x1 << 7) #define BRGPHY_SERDES_ANLPAR_ASYM_PAUSE (0x2 << 7) #define BRGPHY_SERDES_ANLPAR_BOTH_PAUSE (0x3 << 7) /*******************************************************/ /* End: Shared SerDes PHY register definitions */ /*******************************************************/ /*******************************************************/ /* Begin: PHY register values for the 5706 PHY */ /*******************************************************/ /* * Shadow register 0x1C, bit 15 is write enable, * bits 14-10 select function (0x00 to 0x1F). */ #define BRGPHY_MII_SHADOW_1C 0x1C #define BRGPHY_SHADOW_1C_WRITE_EN 0x8000 #define BRGPHY_SHADOW_1C_SELECT_MASK 0x7C00 /* Shadow 0x1C Mode Control Register (select value 0x1F) */ #define BRGPHY_SHADOW_1C_MODE_CTRL (0x1F << 10) /* When set, Regs 0-0x0F are 1000X, else 1000T */ #define BRGPHY_SHADOW_1C_ENA_1000X 0x0001 #define BRGPHY_MII_TEST1 0x1E #define BRGPHY_TEST1_TRIM_EN 0x0010 #define BRGPHY_TEST1_CRC_EN 0x8000 #define BRGPHY_MII_TEST2 0x1F /*******************************************************/ /* End: PHY register values for the 5706 PHY */ /*******************************************************/ /*******************************************************/ /* Begin: PHY register values for the 5708S SerDes PHY */ /*******************************************************/ /* Autoneg Next Page Transmit 1 Regiser */ #define BRGPHY_5708S_ANEG_NXT_PG_XMIT1 0x0B #define BRGPHY_5708S_ANEG_NXT_PG_XMIT1_25G 0x0001 /* Use the BLOCK_ADDR register to select the page for registers 0x10 to 0x1E */ #define BRGPHY_5708S_BLOCK_ADDR 0x1f #define BRGPHY_5708S_DIG_PG0 0x0000 #define BRGPHY_5708S_DIG3_PG2 0x0002 #define BRGPHY_5708S_TX_MISC_PG5 0x0005 /* 5708S SerDes "Digital" Registers (page 0) */ #define BRGPHY_5708S_PG0_1000X_CTL1 0x10 #define BRGPHY_5708S_PG0_1000X_CTL1_AUTODET_EN 0x0010 #define BRGPHY_5708S_PG0_1000X_CTL1_FIBER_MODE 0x0001 #define BRGPHY_5708S_PG0_1000X_STAT1 0x14 #define BRGPHY_5708S_PG0_1000X_STAT1_LINK 0x0002 #define BRGPHY_5708S_PG0_1000X_STAT1_FDX 0x0004 #define BRGPHY_5708S_PG0_1000X_STAT1_SPEED_MASK 0x0018 #define BRGPHY_5708S_PG0_1000X_STAT1_SPEED_10 (0x0 << 3) #define BRGPHY_5708S_PG0_1000X_STAT1_SPEED_100 (0x1 << 3) #define BRGPHY_5708S_PG0_1000X_STAT1_SPEED_1G (0x2 << 3) #define BRGPHY_5708S_PG0_1000X_STAT1_SPEED_25G (0x3 << 3) #define BRGPHY_5708S_PG0_1000X_CTL2 0x11 #define BRGPHY_5708S_PG0_1000X_CTL2_PAR_DET_EN 0x0001 /* 5708S SerDes "Digital 3" Registers (page 2) */ #define BRGPHY_5708S_PG2_DIGCTL_3_0 0x10 #define BRGPHY_5708S_PG2_DIGCTL_3_0_USE_IEEE 0x0001 /* 5708S SerDes "TX Misc" Registers (page 5) */ #define BRGPHY_5708S_PG5_2500STATUS1 0x10 #define BRGPHY_5708S_PG5_TXACTL1 0x15 #define BRGPHY_5708S_PG5_TXACTL3 0x17 /*******************************************************/ /* End: PHY register values for the 5708S SerDes PHY */ /*******************************************************/ +/*******************************************************/ +/* Begin: PHY register values for the 5709S SerDes PHY */ +/*******************************************************/ + +/* 5709S SerDes "General Purpose Status" Registers */ +#define BRGPHY_BLOCK_ADDR_GP_STATUS 0x8120 +#define BRGPHY_GP_STATUS_TOP_ANEG_STATUS 0x1B +#define BRGPHY_GP_STATUS_TOP_ANEG_SPEED_MASK 0x3F00 +#define BRGPHY_GP_STATUS_TOP_ANEG_SPEED_10 0x0000 +#define BRGPHY_GP_STATUS_TOP_ANEG_SPEED_100 0x0100 +#define BRGPHY_GP_STATUS_TOP_ANEG_SPEED_1G 0x0200 +#define BRGPHY_GP_STATUS_TOP_ANEG_SPEED_25G 0x0300 +#define BRGPHY_GP_STATUS_TOP_ANEG_SPEED_1GKX 0x0D00 +#define BRGPHY_GP_STATUS_TOP_ANEG_FDX 0x0008 +#define BRGPHY_GP_STATUS_TOP_ANEG_LINK_UP 0x0004 +#define BRGPHY_GP_STATUS_TOP_ANEG_CL73_COMP 0x0001 + +/* 5709S SerDes "SerDes Digital" Registers */ +#define BRGPHY_BLOCK_ADDR_SERDES_DIG 0x8300 +#define BRGPHY_SERDES_DIG_1000X_CTL1 0x0010 +#define BRGPHY_SD_DIG_1000X_CTL1_AUTODET 0x0010 +#define BRGPHY_SD_DIG_1000X_CTL1_FIBER 0x0001 + +/* 5709S SerDes "Over 1G" Registers */ +#define BRGPHY_BLOCK_ADDR_OVER_1G 0x8320 +#define BRGPHY_OVER_1G_UNFORMAT_PG1 0x19 + +/* 5709S SerDes "Multi-Rate Backplane Ethernet" Registers */ +#define BRGPHY_BLOCK_ADDR_MRBE 0x8350 +#define BRGPHY_MRBE_MSG_PG5_NP 0x10 +#define BRGPHY_MRBE_MSG_PG5_NP_MBRE 0x0001 +#define BRGPHY_MRBE_MSG_PG5_NP_T2 0x0001 + +/* 5709S SerDes "IEEE Clause 73 User B0" Registers */ +#define BRGPHY_BLOCK_ADDR_CL73_USER_B0 0x8370 +#define BRGPHY_CL73_USER_B0_MBRE_CTL1 0x12 +#define BRGPHY_CL73_USER_B0_MBRE_CTL1_NP_AFT_BP 0x2000 +#define BRGPHY_CL73_USER_B0_MBRE_CTL1_STA_MGR 0x4000 +#define BRGPHY_CL73_USER_B0_MBRE_CTL1_ANEG 0x8000 + +/* 5709S SerDes "IEEE Clause 73 User B0" Registers */ +#define BRGPHY_BLOCK_ADDR_ADDR_EXT 0xFFD0 + +/* 5709S SerDes "Combo IEEE 0" Registers */ +#define BRGPHY_BLOCK_ADDR_COMBO_IEEE0 0xFFE0 + +#define BRGPHY_ADDR_EXT 0x1E +#define BRGPHY_BLOCK_ADDR 0x1F + +#define BRGPHY_ADDR_EXT_AN_MMD 0x3800 + +/*******************************************************/ +/* End: PHY register values for the 5709S SerDes PHY */ +/*******************************************************/ + #define BRGPHY_INTRS \ ~(BRGPHY_IMR_LNK_CHG|BRGPHY_IMR_LSP_CHG|BRGPHY_IMR_DUP_CHG) #endif /* _DEV_BRGPHY_MIIREG_H_ */ Index: head/sys/dev/mii/miidevs =================================================================== --- head/sys/dev/mii/miidevs (revision 205298) +++ head/sys/dev/mii/miidevs (revision 205299) @@ -1,252 +1,253 @@ $FreeBSD$ /*$NetBSD: miidevs,v 1.6 1999/05/14 11:37:30 drochner Exp $*/ /*- * Copyright (c) 1998, 1999 The NetBSD Foundation, Inc. * All rights reserved. * * This code is derived from software contributed to The NetBSD Foundation * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, * NASA Ames Research Center. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ /* * List of known MII OUIs. * For a complete list see http://standards.ieee.org/regauth/oui/ * * XXX Vendors do obviously not agree how OUIs (18 bit) are mapped * to the 16 bits available in the id registers. The MII_OUI() macro * in "mii.h" reflects the most obvious way. If a vendor uses a * different mapping, an "xx" prefixed OUI is defined here which is * mangled accordingly to compensate. */ oui AGERE 0x00a0bc Agere Systems oui ALTIMA 0x0010a9 Altima Communications oui AMD 0x00001a Advanced Micro Devices oui ASIX 0x00602e Asix Semiconductor oui ATHEROS 0x001374 Atheros Communications oui BROADCOM 0x001018 Broadcom Corporation oui BROADCOM2 0x000af7 Broadcom Corporation oui CICADA 0x0003F1 Cicada Semiconductor oui DAVICOM 0x00606e Davicom Semiconductor oui ICPLUS 0x0090c3 IC Plus Corp. oui ICS 0x00a0be Integrated Circuit Systems oui INTEL 0x00aa00 Intel oui JATO 0x00e083 Jato Technologies oui JMICRON 0x001b8c JMicron Technologies oui LEVEL1 0x00207b Level 1 oui NATSEMI 0x080017 National Semiconductor oui QUALSEMI 0x006051 Quality Semiconductor oui REALTEK 0x000020 RealTek Semicondctor oui SEEQ 0x00a07d Seeq oui SIS 0x00e006 Silicon Integrated Systems oui SMSC 0x0005be SMSC oui TDK 0x00c039 TDK oui TI 0x080028 Texas Instruments oui VITESSE 0x0001c1 Vitesse Semiconductor oui XAQTI 0x00e0ae XaQti Corp. oui MARVELL 0x005043 Marvell Semiconductor oui xxMARVELL 0x000ac2 Marvell Semiconductor /* in the 79c873, AMD uses another OUI (which matches Davicom!) */ oui xxAMD 0x00606e Advanced Micro Devices /* Intel 82553 A/B steppings */ oui xxINTEL 0x00f800 Intel /* some vendors have the bits swapped within bytes (ie, ordered as on the wire) */ oui xxALTIMA 0x000895 Altima Communications oui xxBROADCOM 0x000818 Broadcom Corporation oui xxBROADCOM_ALT1 0x0050ef Broadcom Corporation oui xxICS 0x00057d Integrated Circuit Systems oui xxSEEQ 0x0005be Seeq oui xxSIS 0x000760 Silicon Integrated Systems oui xxTI 0x100014 Texas Instruments oui xxXAQTI 0x350700 XaQti Corp. /* Level 1 is completely different - from right to left. (Two bits get lost in the third OUI byte.) */ oui xxLEVEL1 0x1e0400 Level 1 /* Don't know what's going on here. */ oui xxDAVICOM 0x006040 Davicom Semiconductor /* This is the OUI of the gigE PHY in the RealTek 8169S/8110S/8211B chips */ oui xxREALTEK 0x000732 /* * List of known models. Grouped by oui. */ /* Agere Systems PHYs */ model AGERE ET1011C 0x0004 ET1011C 10/100/1000baseT PHY /* Altima Communications PHYs */ model xxALTIMA AC101 0x0021 AC101 10/100 media interface model xxALTIMA AC101L 0x0012 AC101L 10/100 media interface model xxALTIMA ACXXX 0x0001 ACXXX 10/100 media interface /* Advanced Micro Devices PHYs */ model AMD 79c973phy 0x0036 Am79c973 internal PHY model AMD 79c978 0x0039 Am79c978 HomePNA PHY model xxAMD 79C873 0x0000 Am79C873/DM9101 10/100 media interface /* Asix semiconductor PHYs. */ model ASIX AX88X9X 0x0031 Ax88x9x internal PHY /* Atheros Communications/Attansic PHYs. */ model ATHEROS F1 0x0001 Atheros F1 10/100/1000 PHY model ATHEROS F2 0x0002 Atheros F2 10/100 PHY /* Broadcom Corp. PHYs. */ model BROADCOM 3C905B 0x0012 3c905B 10/100 internal PHY model BROADCOM 3C905C 0x0017 3c905C 10/100 internal PHY model BROADCOM BCM5201 0x0021 BCM5201 10/100baseTX PHY model BROADCOM BCM5221 0x001e BCM5221 10/100baseTX PHY model BROADCOM BCM4401 0x0036 BCM4401 10/100baseTX PHY model xxBROADCOM BCM5400 0x0004 Broadcom 1000baseTX PHY model xxBROADCOM BCM5401 0x0005 BCM5401 10/100/1000baseTX PHY model xxBROADCOM BCM5411 0x0007 BCM5411 10/100/1000baseTX PHY model xxBROADCOM BCM5754 0x000e BCM5754 10/100/1000baseTX PHY model xxBROADCOM BCM5752 0x0010 BCM5752 10/100/1000baseTX PHY model xxBROADCOM BCM5701 0x0011 BCM5701 10/100/1000baseTX PHY model xxBROADCOM BCM5706 0x0015 BCM5706 10/100/1000baseTX/SX PHY model xxBROADCOM BCM5703 0x0016 BCM5703 10/100/1000baseTX PHY model xxBROADCOM BCM5704 0x0019 BCM5704 10/100/1000baseTX PHY model xxBROADCOM BCM5705 0x001a BCM5705 10/100/1000baseTX PHY model xxBROADCOM BCM5750 0x0018 BCM5750 10/100/1000baseTX PHY model xxBROADCOM BCM54K2 0x002e BCM54K2 10/100/1000baseTX PHY model xxBROADCOM BCM5714 0x0034 BCM5714 10/100/1000baseTX PHY model xxBROADCOM BCM5780 0x0035 BCM5780 10/100/1000baseTX PHY model xxBROADCOM BCM5708C 0x0036 BCM5708C 10/100/1000baseTX PHY model xxBROADCOM_ALT1 BCM5755 0x000c BCM5755 10/100/1000baseTX PHY model xxBROADCOM_ALT1 BCM5787 0x000e BCM5787 10/100/1000baseTX PHY model xxBROADCOM_ALT1 BCM5708S 0x0015 BCM5708S 1000/2500BaseSX PHY model xxBROADCOM_ALT1 BCM5709CAX 0x002c BCM5709C(AX) 10/100/1000baseTX PHY model xxBROADCOM_ALT1 BCM5722 0x002d BCM5722 10/100/1000baseTX PHY model xxBROADCOM_ALT1 BCM5784 0x003a BCM5784 10/100/1000baseTX PHY model xxBROADCOM_ALT1 BCM5709C 0x003c BCM5709C 10/100/1000baseTX PHY model xxBROADCOM_ALT1 BCM5761 0x003d BCM5761 10/100/1000baseTX PHY +model xxBROADCOM_ALT1 BCM5709S 0x003f BCM5709S 1000/2500baseSX PHY model BROADCOM2 BCM5906 0x0004 BCM5906 10/100baseTX PHY /* Cicada Semiconductor PHYs (now owned by Vitesse?) */ model CICADA CS8201 0x0001 Cicada CS8201 10/100/1000TX PHY model CICADA CS8204 0x0004 Cicada CS8204 10/100/1000TX PHY model CICADA VSC8211 0x000b Cicada VSC8211 10/100/1000TX PHY model CICADA CS8201A 0x0020 Cicada CS8201 10/100/1000TX PHY model CICADA CS8201B 0x0021 Cicada CS8201 10/100/1000TX PHY model CICADA CS8244 0x002c Cicada CS8244 10/100/1000TX PHY model VITESSE VSC8601 0x0002 Vitesse VSC8601 10/100/1000TX PHY /* Davicom Semiconductor PHYs */ model DAVICOM DM9102 0x0004 DM9102 10/100 media interface model xxDAVICOM DM9101 0x0000 DM9101 10/100 media interface /* Integrated Circuit Systems PHYs */ model xxICS 1889 0x0001 ICS1889 10/100 media interface model xxICS 1890 0x0002 ICS1890 10/100 media interface model xxICS 1892 0x0003 ICS1892 10/100 media interface model xxICS 1893 0x0004 ICS1893 10/100 media interface /* IC Plus Corp. PHYs */ model ICPLUS IP101 0x0005 IC Plus 10/100 PHY model ICPLUS IP1000A 0x0008 IC Plus 10/100/1000 media interface model ICPLUS IP1001 0x0019 IC Plus IP1001 10/100/1000 media interface /* Intel PHYs */ model xxINTEL I82553AB 0x0000 i83553 10/100 media interface model INTEL I82555 0x0015 i82555 10/100 media interface model INTEL I82562EM 0x0032 i82562EM 10/100 media interface model INTEL I82562ET 0x0033 i82562ET 10/100 media interface model INTEL I82553C 0x0035 i82553 10/100 media interface /* Jato Technologies PHYs */ model JATO BASEX 0x0000 Jato 1000baseX media interface /* JMicron Technologies PHYs */ model JMICRON JMP211 0x0021 JMP211 10/100/1000 media interface model JMICRON JMP202 0x0022 JMP202 10/100 media interface /* Level 1 PHYs */ model xxLEVEL1 LXT970 0x0000 LXT970 10/100 media interface /* National Semiconductor PHYs */ model NATSEMI DP83840 0x0000 DP83840 10/100 media interface model NATSEMI DP83843 0x0001 DP83843 10/100 media interface model NATSEMI DP83815 0x0002 DP83815 10/100 media interface model NATSEMI DP83847 0x0003 DP83847 10/100 media interface model NATSEMI DP83891 0x0005 DP83891 10/100/1000 media interface model NATSEMI DP83861 0x0006 DP83861 10/100/1000 media interface model NATSEMI DP83865 0x0007 DP83865 10/100/1000 media interface /* Quality Semiconductor PHYs */ model QUALSEMI QS6612 0x0000 QS6612 10/100 media interface /* RealTek Semiconductor PHYs */ model REALTEK RTL8201L 0x0020 RTL8201L 10/100 media interface model xxREALTEK RTL8305SC 0x0005 RTL8305SC 10/100 802.1q switch model xxREALTEK RTL8169S 0x0011 RTL8169S/8110S/8211B media interface /* Seeq PHYs */ model xxSEEQ 80220 0x0003 Seeq 80220 10/100 media interface model xxSEEQ 84220 0x0004 Seeq 84220 10/100 media interface /* Silicon Integrated Systems PHYs */ model xxSIS 900 0x0000 SiS 900 10/100 media interface /* SMSC PHYs */ model SMSC LAN83C183 0x0004 SMSC LAN83C183 10/100 media interface /* TDK */ model TDK 78Q2120 0x0014 TDK 78Q2120 media interface /* Texas Instruments PHYs */ model xxTI TLAN10T 0x0001 ThunderLAN 10baseT media interface model xxTI 100VGPMI 0x0002 ThunderLAN 100VG-AnyLan media interface /* XaQti Corp. PHYs. */ model XAQTI XMACII 0x0000 XaQti Corp. XMAC II gigabit interface /* Marvell Semiconductor PHYs */ model MARVELL E1000 0x0000 Marvell 88E1000 Gigabit PHY model MARVELL E1011 0x0002 Marvell 88E1011 Gigabit PHY model MARVELL E1000_3 0x0003 Marvell 88E1000 Gigabit PHY model MARVELL E1000S 0x0004 Marvell 88E1000S Gigabit PHY model MARVELL E1000_5 0x0005 Marvell 88E1000 Gigabit PHY model MARVELL E1000_6 0x0006 Marvell 88E1000 Gigabit PHY model MARVELL E3082 0x0008 Marvell 88E3082 10/100 Fast Ethernet PHY model MARVELL E1112 0x0009 Marvell 88E1112 Gigabit PHY model MARVELL E1149 0x000b Marvell 88E1149 Gigabit PHY model MARVELL E1111 0x000c Marvell 88E1111 Gigabit PHY model MARVELL E1116 0x0021 Marvell 88E1116 Gigabit PHY model MARVELL E1116R 0x0024 Marvell 88E1116R Gigabit PHY model MARVELL E1118 0x0022 Marvell 88E1118 Gigabit PHY model MARVELL E3016 0x0026 Marvell 88E3016 10/100 Fast Ethernet PHY model xxMARVELL E1000 0x0005 Marvell 88E1000 Gigabit PHY model xxMARVELL E1011 0x0002 Marvell 88E1011 Gigabit PHY model xxMARVELL E1000_3 0x0003 Marvell 88E1000 Gigabit PHY model xxMARVELL E1000_5 0x0005 Marvell 88E1000 Gigabit PHY model xxMARVELL E1111 0x000c Marvell 88E1111 Gigabit PHY