Provide workaround for the ages old bug affecting certain BCM5708S

chip revision often found in the blades and resulting in interfaces
not sensing carrier signal. Looking at all problem reports it
appears that it only affects some very specific silicon revision
(ASIC (0x57081021); Rev (B2)) and version of the PHY that
supports 1000baseSX-FDX media only. Therefore, narrow the scope of
workaround to combination of that revision and media type. Given
that the first report on this issue is dated back to 2007, there is
not much hope that this issue will ever be properly resolved.

Among affected systems are IBM HS21, Intel SBXD132 and HP BL460c.

PR:		118238, 122551, 140970
MFC after:	1 month
This commit is contained in:
Maxim Sobolev 2010-03-10 05:19:14 +00:00
parent 32202de70d
commit 6b07566596

View File

@ -66,14 +66,17 @@ __FBSDID("$FreeBSD$");
static int brgphy_probe(device_t);
static int brgphy_attach(device_t);
#define BCM5708S_BAD_CHIPID 0x57081021
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_5706S 0x0001
#define BRGPHY_5708S 0x0002
#define BRGPHY_NOANWAIT 0x0004
int bce_phy_flags; /* PHY flags transferred from the MAC driver */
};
@ -291,6 +294,19 @@ brgphy_attach(device_t dev)
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 &&
(bce_sc->bce_chipid == BCM5708S_BAD_CHIPID)) {
/*
* There appears to be certain silicon revision
* usually used in 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;
}
}
@ -544,7 +560,8 @@ brgphy_status(struct mii_softc *sc)
/* Autoneg is still in progress. */
if ((bmcr & BRGPHY_BMCR_AUTOEN) &&
(bmsr & BRGPHY_BMSR_ACOMP) == 0) {
(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;