summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorjkim <jkim@FreeBSD.org>2007-02-12 23:58:52 +0000
committerjkim <jkim@FreeBSD.org>2007-02-12 23:58:52 +0000
commit53d0372949779ab6c304823ce666e28ada25c981 (patch)
tree1bbcf0bc1d9e6bf84b8dafc7f19d0f0ee1fdffae /sys
parentc0b996086f6d99df9476393ae809acab6994d3b0 (diff)
downloadFreeBSD-src-53d0372949779ab6c304823ce666e28ada25c981.zip
FreeBSD-src-53d0372949779ab6c304823ce666e28ada25c981.tar.gz
Add BCM5701 A0/B0 CRC bug workaround. Magic values taken from Linux driver.
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/bge/if_bge.c3
-rw-r--r--sys/dev/bge/if_bgereg.h1
-rw-r--r--sys/dev/mii/brgphy.c22
3 files changed, 26 insertions, 0 deletions
diff --git a/sys/dev/bge/if_bge.c b/sys/dev/bge/if_bge.c
index 58b5dbf..572ba46 100644
--- a/sys/dev/bge/if_bge.c
+++ b/sys/dev/bge/if_bge.c
@@ -2216,6 +2216,9 @@ bge_attach(device_t dev)
}
/* Set various bug flags. */
+ if (sc->bge_chipid == BGE_CHIPID_BCM5701_A0 ||
+ sc->bge_chipid == BGE_CHIPID_BCM5701_B0)
+ sc->bge_flags |= BGE_FLAG_CRC_BUG;
if (sc->bge_chiprev == BGE_CHIPREV_5703_AX ||
sc->bge_chiprev == BGE_CHIPREV_5704_AX)
sc->bge_flags |= BGE_FLAG_ADC_BUG;
diff --git a/sys/dev/bge/if_bgereg.h b/sys/dev/bge/if_bgereg.h
index fa577a0..d77bd5c4 100644
--- a/sys/dev/bge/if_bgereg.h
+++ b/sys/dev/bge/if_bgereg.h
@@ -2467,6 +2467,7 @@ struct bge_softc {
#define BGE_FLAG_JITTER_BUG 0x01000000
#define BGE_FLAG_BER_BUG 0x02000000
#define BGE_FLAG_ADJUST_TRIM 0x04000000
+#define BGE_FLAG_CRC_BUG 0x08000000
uint32_t bge_chipid;
uint8_t bge_asicrev;
uint8_t bge_chiprev;
diff --git a/sys/dev/mii/brgphy.c b/sys/dev/mii/brgphy.c
index 37f40b1..3c56585 100644
--- a/sys/dev/mii/brgphy.c
+++ b/sys/dev/mii/brgphy.c
@@ -103,6 +103,7 @@ 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);
@@ -612,6 +613,25 @@ brgphy_fixup_ber_bug(struct mii_softc *sc)
}
static void
+brgphy_fixup_crc_bug(struct mii_softc *sc)
+{
+ static const struct {
+ int reg;
+ uint16_t val;
+ } dspcode[] = {
+ { BRGPHY_MII_DSP_ADDR_REG, 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 {
@@ -716,6 +736,8 @@ brgphy_reset(struct mii_softc *sc)
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);
OpenPOWER on IntegriCloud