- Added support for 5709S/5716S PHYs.

Submitted by:	pyunyh
MFC after:	2 weeks
This commit is contained in:
David Christensen 2010-03-18 20:57:57 +00:00
parent 6b4391d786
commit b249ff39a4
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=205299
3 changed files with 158 additions and 23 deletions

View File

@ -75,6 +75,7 @@ struct brgphy_softc {
#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 */
};
@ -139,6 +140,7 @@ static const struct mii_phydesc brgphys[] = {
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
};
@ -216,30 +218,34 @@ brgphy_attach(device_t dev)
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");
@ -631,6 +637,7 @@ 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);
/* 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;
@ -642,11 +649,40 @@ brgphy_status(struct mii_softc *sc)
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
@ -967,6 +1003,7 @@ brgphy_reset(struct mii_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);
@ -1089,7 +1126,49 @@ 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) {
} 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);

View File

@ -359,6 +359,61 @@
/* 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)

View File

@ -150,6 +150,7 @@ 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?) */