- Added support for BCM5709 and BCM5716.
MFC after: 2 weeks
This commit is contained in:
parent
7752e34d05
commit
d75672d1c4
@ -74,7 +74,7 @@ struct brgphy_softc {
|
||||
int serdes_flags; /* Keeps track of the serdes type used */
|
||||
#define BRGPHY_5706S 0x0001
|
||||
#define BRGPHY_5708S 0x0002
|
||||
int bce_phy_flags; /* PHY flags transferred from the MAC driver */
|
||||
int bce_phy_flags; /* PHY flags transferred from the MAC driver */
|
||||
};
|
||||
|
||||
static device_method_t brgphy_methods[] = {
|
||||
@ -231,7 +231,7 @@ brgphy_attach(device_t dev)
|
||||
bce_sc = ifp->if_softc;
|
||||
}
|
||||
|
||||
/* Todo: Need to add additional controllers such as 5787F */
|
||||
/* 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 &&
|
||||
@ -245,6 +245,7 @@ brgphy_attach(device_t dev)
|
||||
|
||||
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);
|
||||
@ -281,7 +282,7 @@ brgphy_attach(device_t dev)
|
||||
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 */
|
||||
/* 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, ");
|
||||
@ -425,12 +426,20 @@ 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;
|
||||
@ -446,6 +455,8 @@ brgphy_setmedia(struct mii_softc *sc, int media, int master)
|
||||
bmcr = BRGPHY_S10;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Calculate duplex settings for 1000BasetT/1000BaseX. */
|
||||
if ((media & IFM_GMASK) == IFM_FDX) {
|
||||
bmcr |= BRGPHY_BMCR_FDX;
|
||||
gig = BRGPHY_1000CTL_AFD;
|
||||
@ -453,18 +464,27 @@ brgphy_setmedia(struct mii_softc *sc, int media, int master)
|
||||
gig = BRGPHY_1000CTL_AHD;
|
||||
}
|
||||
|
||||
/* Force loopback to disconnect PHY for Ethernet medium. */
|
||||
brgphy_enable_loopback(sc);
|
||||
PHY_WRITE(sc, BRGPHY_MII_1000CTL, 0);
|
||||
PHY_WRITE(sc, BRGPHY_MII_BMCR, bmcr);
|
||||
PHY_WRITE(sc, BRGPHY_MII_ANAR, BRGPHY_SEL_TYPE);
|
||||
|
||||
/* 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;
|
||||
|
||||
@ -482,13 +502,19 @@ brgphy_setmedia(struct mii_softc *sc, int media, int master)
|
||||
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) */
|
||||
/****************************************************************************/
|
||||
/* 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)
|
||||
{
|
||||
@ -568,7 +594,6 @@ brgphy_status(struct mii_softc *sc)
|
||||
PHY_WRITE(sc, BRGPHY_5708S_BLOCK_ADDR, BRGPHY_5708S_DIG_PG0);
|
||||
xstat = PHY_READ(sc, BRGPHY_5708S_PG0_1000X_STAT1);
|
||||
|
||||
/* Todo: Create #defines for hard coded values */
|
||||
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;
|
||||
@ -603,6 +628,7 @@ brgphy_status(struct mii_softc *sc)
|
||||
mii->mii_media_active |= IFM_FLAG0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Todo: Add support for fiber settings too. */
|
||||
#endif
|
||||
|
||||
@ -643,6 +669,7 @@ brgphy_mii_phy_auto(struct mii_softc *sc)
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* Enable loopback to force the link down. */
|
||||
static void
|
||||
brgphy_enable_loopback(struct mii_softc *sc)
|
||||
@ -819,6 +846,20 @@ brgphy_fixup_jitter_bug(struct mii_softc *sc)
|
||||
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)
|
||||
{
|
||||
@ -830,6 +871,7 @@ brgphy_ethernet_wirespeed(struct mii_softc *sc)
|
||||
PHY_WRITE(sc, BRGPHY_MII_AUXCTL, val | (1 << 15) | (1 << 4));
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
brgphy_jumbo_settings(struct mii_softc *sc, u_long mtu)
|
||||
{
|
||||
@ -871,9 +913,10 @@ brgphy_reset(struct mii_softc *sc)
|
||||
struct bce_softc *bce_sc = NULL;
|
||||
struct ifnet *ifp;
|
||||
|
||||
/* Perform a standard PHY reset. */
|
||||
mii_phy_reset(sc);
|
||||
|
||||
/* Handle any PHY specific procedures to finish the reset. */
|
||||
/* Handle any PHY specific procedures following the reset. */
|
||||
switch (bsc->mii_oui) {
|
||||
case MII_OUI_BROADCOM:
|
||||
break;
|
||||
@ -988,6 +1031,13 @@ brgphy_reset(struct mii_softc *sc)
|
||||
PHY_WRITE(sc, BRGPHY_5708S_BLOCK_ADDR,
|
||||
BRGPHY_5708S_DIG_PG0);
|
||||
}
|
||||
} 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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user