Fix BCM5709 PHY detection for ethernet PHYs (the SerDes case being already

handled):
- export bge(4) and bnx(4) CHIP ID and PHY flags to brgphy(4). Move to
"unsigned int" rather than "int", and reuse the same softc members for
chipid and phyflags (behavior controlled by the sc_isbge/isbnx boolean).
- apply bug fix for revisions A and B, so that autonegotiation can
complete (from OpenBSD).

Bug reported by Rivo Nurges via private mail, patch tested and
confirmed working by him (with thanks!)
This commit is contained in:
jym 2011-05-02 09:03:10 +00:00
parent a76f8ee3b0
commit a30b258c9c
4 changed files with 61 additions and 32 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: brgphy.c,v 1.57 2010/12/09 23:25:49 jym Exp $ */
/* $NetBSD: brgphy.c,v 1.58 2011/05/02 09:03:10 jym Exp $ */
/*-
* Copyright (c) 1998, 1999, 2000, 2001 The NetBSD Foundation, Inc.
@ -62,7 +62,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: brgphy.c,v 1.57 2010/12/09 23:25:49 jym Exp $");
__KERNEL_RCSID(0, "$NetBSD: brgphy.c,v 1.58 2011/05/02 09:03:10 jym Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -90,8 +90,8 @@ struct brgphy_softc {
struct mii_softc sc_mii;
bool sc_isbge;
bool sc_isbnx;
int sc_bge_flags;
int sc_bnx_flags;
uint32_t sc_chipid; /* parent's chipid */
uint32_t sc_phyflags; /* parent's phyflags */
};
CFATTACH_DECL3_NEW(brgphy, sizeof(struct brgphy_softc),
@ -111,6 +111,7 @@ static void brgphy_adc_bug(struct mii_softc *);
static void brgphy_5704_a0_bug(struct mii_softc *);
static void brgphy_ber_bug(struct mii_softc *);
static void brgphy_crc_bug(struct mii_softc *);
static void brgphy_disable_early_dac(struct mii_softc *);
static void brgphy_jumbo_settings(struct mii_softc *);
static void brgphy_eth_wirespeed(struct mii_softc *);
@ -251,18 +252,19 @@ brgphyattach(device_t parent, device_t self, void *aux)
sc->mii_extcapabilities = PHY_READ(sc, MII_EXTSR);
if (device_is_a(parent, "bge")) {
if (device_is_a(parent, "bge"))
bsc->sc_isbge = true;
dict = device_properties(parent);
if (!prop_dictionary_get_uint32(dict, "phyflags",
&bsc->sc_bge_flags))
aprint_error_dev(self, "failed to get phyflags");
} else if (device_is_a(parent, "bnx")) {
else if (device_is_a(parent, "bnx"))
bsc->sc_isbnx = true;
if (bsc->sc_isbge || bsc->sc_isbnx) {
dict = device_properties(parent);
if (!prop_dictionary_get_uint32(dict, "phyflags",
&bsc->sc_bnx_flags))
aprint_error_dev(self, "failed to get phyflags");
&bsc->sc_phyflags))
aprint_error_dev(self, "failed to get phyflags\n");
if (!prop_dictionary_get_uint32(dict, "chipid",
&bsc->sc_chipid))
aprint_error_dev(self, "failed to get chipid\n");
}
aprint_normal_dev(self, "");
@ -287,7 +289,7 @@ brgphyattach(device_t parent, device_t self, void *aux)
* on the BCM5708S and BCM5709S controllers.
*/
#define ADD(m, c) ifmedia_add(&mii->mii_media, (m), (c), NULL)
if (bsc->sc_bnx_flags
if (bsc->sc_phyflags
& BNX_PHY_2_5G_CAPABLE_FLAG) {
ADD(IFM_MAKEWORD(IFM_ETHER, IFM_2500_SX,
IFM_FDX, sc->mii_inst), 0);
@ -627,18 +629,19 @@ brgphy_reset(struct mii_softc *sc)
if (bsc->sc_isbge) {
if (!(sc->mii_flags & MIIF_HAVEFIBER)) {
if (bsc->sc_bge_flags & BGE_PHY_ADC_BUG)
if (bsc->sc_phyflags & BGE_PHY_ADC_BUG)
brgphy_adc_bug(sc);
if (bsc->sc_bge_flags & BGE_PHY_5704_A0_BUG)
if (bsc->sc_phyflags & BGE_PHY_5704_A0_BUG)
brgphy_5704_a0_bug(sc);
if (bsc->sc_bge_flags & BGE_PHY_BER_BUG)
if (bsc->sc_phyflags & BGE_PHY_BER_BUG)
brgphy_ber_bug(sc);
else if (bsc->sc_bge_flags & BGE_PHY_JITTER_BUG) {
else if (bsc->sc_phyflags & BGE_PHY_JITTER_BUG) {
PHY_WRITE(sc, BRGPHY_MII_AUXCTL, 0x0c00);
PHY_WRITE(sc, BRGPHY_MII_DSP_ADDR_REG,
0x000a);
if (bsc->sc_bge_flags & BGE_PHY_ADJUST_TRIM) {
if (bsc->sc_phyflags
& BGE_PHY_ADJUST_TRIM) {
PHY_WRITE(sc, BRGPHY_MII_DSP_RW_PORT,
0x110b);
PHY_WRITE(sc, BRGPHY_TEST1,
@ -650,11 +653,11 @@ brgphy_reset(struct mii_softc *sc)
PHY_WRITE(sc, BRGPHY_MII_AUXCTL, 0x0400);
}
if (bsc->sc_bge_flags & BGE_PHY_CRC_BUG)
if (bsc->sc_phyflags & BGE_PHY_CRC_BUG)
brgphy_crc_bug(sc);
/* Set Jumbo frame settings in the PHY. */
if (bsc->sc_bge_flags & BGE_JUMBO_CAPABLE)
if (bsc->sc_phyflags & BGE_JUMBO_CAPABLE)
brgphy_jumbo_settings(sc);
/* Adjust output voltage */
@ -662,12 +665,12 @@ brgphy_reset(struct mii_softc *sc)
PHY_WRITE(sc, BRGPHY_MII_EPHY_PTEST, 0x12);
/* Enable Ethernet@Wirespeed */
if (!(bsc->sc_bge_flags & BGE_NO_ETH_WIRE_SPEED))
if (!(bsc->sc_phyflags & BGE_NO_ETH_WIRE_SPEED))
brgphy_eth_wirespeed(sc);
#if 0
/* Enable Link LED on Dell boxes */
if (bsc->sc_bge_flags & BGE_NO_3LED) {
if (bsc->sc_phyflags & BGE_NO_3LED) {
PHY_WRITE(sc, BRGPHY_MII_PHY_EXTCTL,
PHY_READ(sc, BRGPHY_MII_PHY_EXTCTL)
& ~BRGPHY_PHY_EXTCTL_3_LED);
@ -737,7 +740,7 @@ brgphy_reset(struct mii_softc *sc)
~BRGPHY_SD_DIG_1000X_CTL1_AUTODET) |
BRGPHY_SD_DIG_1000X_CTL1_FIBER);
if (bsc->sc_bnx_flags & BNX_PHY_2_5G_CAPABLE_FLAG) {
if (bsc->sc_phyflags & BNX_PHY_2_5G_CAPABLE_FLAG) {
/* Select the Over 1G block of the AN MMD. */
PHY_WRITE(sc, BRGPHY_BLOCK_ADDR,
BRGPHY_BLOCK_ADDR_OVER_1G);
@ -777,6 +780,16 @@ brgphy_reset(struct mii_softc *sc)
PHY_WRITE(sc, BRGPHY_BLOCK_ADDR,
BRGPHY_BLOCK_ADDR_COMBO_IEEE0);
} else if (_BNX_CHIP_NUM(bsc->sc_chipid) == BNX_CHIP_NUM_5709) {
if (_BNX_CHIP_REV(bsc->sc_chipid) == BNX_CHIP_REV_Ax ||
_BNX_CHIP_REV(bsc->sc_chipid) == BNX_CHIP_REV_Bx)
brgphy_disable_early_dac(sc);
/* Set Jumbo frame settings in the PHY. */
brgphy_jumbo_settings(sc);
/* Enable Ethernet@Wirespeed */
brgphy_eth_wirespeed(sc);
} else {
if (!(sc->mii_flags & MIIF_HAVEFIBER)) {
brgphy_ber_bug(sc);
@ -954,6 +967,18 @@ brgphy_crc_bug(struct mii_softc *sc)
PHY_WRITE(sc, dspcode[i].reg, dspcode[i].val);
}
static void
brgphy_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_jumbo_settings(struct mii_softc *sc)
{

View File

@ -1,4 +1,4 @@
/* $NetBSD: if_bge.c,v 1.194 2011/04/18 22:05:39 buhrow Exp $ */
/* $NetBSD: if_bge.c,v 1.195 2011/05/02 09:03:10 jym Exp $ */
/*
* Copyright (c) 2001 Wind River Systems
@ -79,7 +79,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: if_bge.c,v 1.194 2011/04/18 22:05:39 buhrow Exp $");
__KERNEL_RCSID(0, "$NetBSD: if_bge.c,v 1.195 2011/05/02 09:03:10 jym Exp $");
#include "vlan.h"
#include "rnd.h"
@ -2959,9 +2959,10 @@ bge_attach(device_t parent, device_t self, void *aux)
sc->bge_flags |= BGE_PHY_FIBER_TBI;
}
/* set phyflags before mii_attach() */
/* set phyflags and chipid before mii_attach() */
dict = device_properties(self);
prop_dictionary_set_uint32(dict, "phyflags", sc->bge_flags);
prop_dictionary_set_uint32(dict, "chipid", sc->bge_chipid);
if (sc->bge_flags & BGE_PHY_FIBER_TBI) {
ifmedia_init(&sc->bge_ifmedia, IFM_IMASK, bge_ifmedia_upd,

View File

@ -1,4 +1,4 @@
/* $NetBSD: if_bnx.c,v 1.42 2011/01/26 00:09:27 dyoung Exp $ */
/* $NetBSD: if_bnx.c,v 1.43 2011/05/02 09:03:10 jym Exp $ */
/* $OpenBSD: if_bnx.c,v 1.85 2009/11/09 14:32:41 dlg Exp $ */
/*-
@ -35,7 +35,7 @@
#if 0
__FBSDID("$FreeBSD: src/sys/dev/bce/if_bce.c,v 1.3 2006/04/13 14:12:26 ru Exp $");
#endif
__KERNEL_RCSID(0, "$NetBSD: if_bnx.c,v 1.42 2011/01/26 00:09:27 dyoung Exp $");
__KERNEL_RCSID(0, "$NetBSD: if_bnx.c,v 1.43 2011/05/02 09:03:10 jym Exp $");
/*
* The following controllers are supported by this driver:
@ -717,9 +717,10 @@ bnx_attach(device_t parent, device_t self, void *aux)
ifmedia_init(&sc->bnx_mii.mii_media, 0, ether_mediachange,
ether_mediastatus);
/* set phyflags before mii_attach() */
/* set phyflags and chipid before mii_attach() */
dict = device_properties(self);
prop_dictionary_set_uint32(dict, "phyflags", sc->bnx_phy_flags);
prop_dictionary_set_uint32(dict, "chipid", sc->bnx_chipid);
if (sc->bnx_phy_flags & BNX_PHY_SERDES_FLAG)
mii_flags |= MIIF_HAVEFIBER;

View File

@ -1,4 +1,4 @@
/* $NetBSD: if_bnxreg.h,v 1.13 2010/12/11 14:28:38 martin Exp $ */
/* $NetBSD: if_bnxreg.h,v 1.14 2011/05/02 09:03:10 jym Exp $ */
/* $OpenBSD: if_bnxreg.h,v 1.33 2009/09/05 16:02:28 claudio Exp $ */
/*-
@ -194,13 +194,15 @@
/* chip num:16-31, rev:12-15, metal:4-11, bond_id:0-3 */
#define BNX_CHIP_NUM(sc) (((sc)->bnx_chipid) & 0xffff0000)
#define _BNX_CHIP_NUM(chipid) ((chipid) & 0xffff0000)
#define BNX_CHIP_NUM(sc) _BNX_CHIP_NUM((sc)->bnx_chipid)
#define BNX_CHIP_NUM_5706 0x57060000
#define BNX_CHIP_NUM_5708 0x57080000
#define BNX_CHIP_NUM_5709 0x57090000
#define BNX_CHIP_NUM_5716 0x57160000
#define BNX_CHIP_REV(sc) (((sc)->bnx_chipid) & 0x0000f000)
#define _BNX_CHIP_REV(chipid) ((chipid) & 0x0000f000)
#define BNX_CHIP_REV(sc) _BNX_CHIP_REV((sc)->bnx_chipid)
#define BNX_CHIP_REV_Ax 0x00000000
#define BNX_CHIP_REV_Bx 0x00001000
#define BNX_CHIP_REV_Cx 0x00002000