Index: sys/dev/bge/if_bge.c =================================================================== RCS file: /home/ncvs/src/sys/dev/bge/if_bge.c,v retrieving revision 1.172 diff -u -r1.172 if_bge.c --- sys/dev/bge/if_bge.c 26 Dec 2006 18:33:55 -0000 1.172 +++ sys/dev/bge/if_bge.c 9 Jan 2007 02:50:26 -0000 @@ -2197,25 +2197,36 @@ case BGE_ASICREV_BCM5704: sc->bge_flags |= BGE_FLAG_5700_FAMILY | BGE_FLAG_JUMBO; break; - case BGE_ASICREV_BCM5714_A0: case BGE_ASICREV_BCM5780: case BGE_ASICREV_BCM5714: sc->bge_flags |= BGE_FLAG_5714_FAMILY /* | BGE_FLAG_JUMBO */; - /* Fall through */ - + /* FALLTHRU */ case BGE_ASICREV_BCM5750: case BGE_ASICREV_BCM5752: case BGE_ASICREV_BCM5755: case BGE_ASICREV_BCM5787: sc->bge_flags |= BGE_FLAG_575X_PLUS; - /* Fall through */ - + /* FALLTHRU */ case BGE_ASICREV_BCM5705: sc->bge_flags |= BGE_FLAG_5705_PLUS; break; } + /* Set various bug flags. */ + if (sc->bge_chiprev == BGE_CHIPREV_5703_AX || + sc->bge_chiprev == BGE_CHIPREV_5704_AX) + sc->bge_flags |= BGE_FLAG_ADC_BUG; + if (sc->bge_chipid == BGE_CHIPID_BCM5704_A0) + sc->bge_flags |= BGE_FLAG_5704_A0_BUG; + if (BGE_IS_5705_PLUS(sc)) { + if (sc->bge_asicrev == BGE_ASICREV_BCM5755 || + sc->bge_asicrev == BGE_ASICREV_BCM5787) + sc->bge_flags |= BGE_FLAG_JITTER_BUG; + else + sc->bge_flags |= BGE_FLAG_BER_BUG; + } + /* * Check if this is a PCI-X or PCI Express device. */ Index: sys/dev/bge/if_bgereg.h =================================================================== RCS file: /home/ncvs/src/sys/dev/bge/if_bgereg.h,v retrieving revision 1.65 diff -u -r1.65 if_bgereg.h --- sys/dev/bge/if_bgereg.h 22 Dec 2006 02:59:58 -0000 1.65 +++ sys/dev/bge/if_bgereg.h 9 Jan 2007 02:50:27 -0000 @@ -303,6 +303,9 @@ #define BGE_CHIPREV_5700_BX 0x71 #define BGE_CHIPREV_5700_CX 0x72 #define BGE_CHIPREV_5701_AX 0x00 +#define BGE_CHIPREV_5703_AX 0x10 +#define BGE_CHIPREV_5704_AX 0x20 +#define BGE_CHIPREV_5704_BX 0x21 #define BGE_CHIPREV_5750_AX 0x40 #define BGE_CHIPREV_5750_BX 0x41 @@ -2447,16 +2450,21 @@ uint32_t bge_flags; #define BGE_FLAG_EXTRAM 0x00000001 /* External SSRAM (unused) */ #define BGE_FLAG_TBI 0x00000002 -#define BGE_FLAG_RX_ALIGNBUG 0x00000004 -#define BGE_FLAG_NO3LED 0x00000008 +#define BGE_FLAG_JUMBO 0x00000004 #define BGE_FLAG_PCIX 0x00000010 #define BGE_FLAG_PCIE 0x00000020 -#define BGE_FLAG_JUMBO 0x00000040 +#define BGE_FLAG_MSI 0x00000040 #define BGE_FLAG_5700_FAMILY 0x00000100 #define BGE_FLAG_5705_PLUS 0x00000200 #define BGE_FLAG_5714_FAMILY 0x00000400 #define BGE_FLAG_575X_PLUS 0x00000800 -#define BGE_FLAG_MSI 0x00001000 +#define BGE_FLAG_RX_ALIGNBUG 0x00010000 +#define BGE_FLAG_NO3LED 0x00020000 +#define BGE_FLAG_ADC_BUG 0x00040000 +#define BGE_FLAG_5704_A0_BUG 0x00080000 +#define BGE_FLAG_JITTER_BUG 0x00100000 +#define BGE_FLAG_BER_BUG 0x00200000 + uint32_t bge_chipid; uint8_t bge_asicrev; uint8_t bge_chiprev; Index: sys/dev/mii/brgphy.c =================================================================== RCS file: /home/ncvs/src/sys/dev/mii/brgphy.c,v retrieving revision 1.52 diff -u -r1.52 brgphy.c --- sys/dev/mii/brgphy.c 20 Dec 2006 00:34:12 -0000 1.52 +++ sys/dev/mii/brgphy.c 9 Jan 2007 02:50:27 -0000 @@ -93,9 +93,12 @@ static void brgphy_loop(struct mii_softc *); static void bcm5401_load_dspcode(struct mii_softc *); static void bcm5411_load_dspcode(struct mii_softc *); -static void bcm5703_load_dspcode(struct mii_softc *); -static void bcm5750_load_dspcode(struct mii_softc *); +static void brgphy_fixup_adc_bug(struct mii_softc *); +static void brgphy_fixup_5704_a0_bug(struct mii_softc *); +static void brgphy_fixup_ber_bug(struct mii_softc *); +static void brgphy_fixup_jitter_bug(struct mii_softc *); static int brgphy_mii_model; +static int brgphy_mii_rev; static const struct mii_phydesc brgphys[] = { MII_PHY_DESC(xxBROADCOM, BCM5400), @@ -112,6 +115,7 @@ MII_PHY_DESC(xxBROADCOM, BCM5752), MII_PHY_DESC(xxBROADCOM, BCM5754), MII_PHY_DESC(xxBROADCOM, BCM5780), + MII_PHY_DESC(xxBROADCOM_ALT1, BCM5787), MII_PHY_END }; @@ -158,6 +162,7 @@ #endif brgphy_mii_model = MII_MODEL(ma->mii_id2); + brgphy_mii_rev = MII_REV(ma->mii_id2); brgphy_reset(sc); sc->mii_capabilities = PHY_READ(sc, MII_BMSR) & ma->mii_capmask; @@ -303,9 +308,12 @@ cmd == MII_MEDIACHG) { switch (brgphy_mii_model) { case MII_MODEL_xxBROADCOM_BCM5400: - case MII_MODEL_xxBROADCOM_BCM5401: bcm5401_load_dspcode(sc); break; + case MII_MODEL_xxBROADCOM_BCM5401: + if (brgphy_mii_rev == 1 || brgphy_mii_rev == 3) + bcm5401_load_dspcode(sc); + break; case MII_MODEL_xxBROADCOM_BCM5411: bcm5411_load_dspcode(sc); break; @@ -515,7 +523,7 @@ } static void -bcm5703_load_dspcode(struct mii_softc *sc) +brgphy_fixup_adc_bug(struct mii_softc *sc) { static const struct { int reg; @@ -533,7 +541,7 @@ } static void -bcm5704_load_dspcode(struct mii_softc *sc) +brgphy_fixup_5704_a0_bug(struct mii_softc *sc) { static const struct { int reg; @@ -550,7 +558,7 @@ } static void -bcm5750_load_dspcode(struct mii_softc *sc) +brgphy_fixup_ber_bug(struct mii_softc *sc) { static const struct { int reg; @@ -573,6 +581,25 @@ } static void +brgphy_fixup_jitter_bug(struct mii_softc *sc) +{ + static const struct { + int reg; + uint16_t val; + } dspcode[] = { + { BRGPHY_MII_AUXCTL, 0x0c00 }, + { BRGPHY_MII_DSP_ADDR_REG, 0x000a }, + { BRGPHY_MII_DSP_RW_PORT, 0x010b }, + { BRGPHY_MII_AUXCTL, 0x0400 }, + { 0, 0 }, + }; + int i; + + for (i = 0; dspcode[i].reg != 0; i++) + PHY_WRITE(sc, dspcode[i].reg, dspcode[i].val); +} + +static void brgphy_reset(struct mii_softc *sc) { u_int32_t val; @@ -584,26 +611,15 @@ switch (brgphy_mii_model) { case MII_MODEL_xxBROADCOM_BCM5400: - case MII_MODEL_xxBROADCOM_BCM5401: bcm5401_load_dspcode(sc); break; + case MII_MODEL_xxBROADCOM_BCM5401: + if (brgphy_mii_rev == 1 || brgphy_mii_rev == 3) + bcm5401_load_dspcode(sc); + break; case MII_MODEL_xxBROADCOM_BCM5411: bcm5411_load_dspcode(sc); break; - case MII_MODEL_xxBROADCOM_BCM5703: - bcm5703_load_dspcode(sc); - break; - case MII_MODEL_xxBROADCOM_BCM5704: - bcm5704_load_dspcode(sc); - break; - case MII_MODEL_xxBROADCOM_BCM5750: - case MII_MODEL_xxBROADCOM_BCM5752: - case MII_MODEL_xxBROADCOM_BCM5714: - case MII_MODEL_xxBROADCOM_BCM5780: - case MII_MODEL_xxBROADCOM_BCM5706C: - case MII_MODEL_xxBROADCOM_BCM5708C: - bcm5750_load_dspcode(sc); - break; } ifp = sc->mii_pdata->mii_ifp; @@ -639,6 +655,16 @@ PHY_READ(sc, BRGPHY_MII_PHY_EXTCTL) & ~BRGPHY_PHY_EXTCTL_3_LED); } + + /* Fix up various bugs */ + if (bge_sc->bge_flags & BGE_FLAG_ADC_BUG) + brgphy_fixup_adc_bug(sc); + if (bge_sc->bge_flags & BGE_FLAG_5704_A0_BUG) + brgphy_fixup_5704_a0_bug(sc); + if (bge_sc->bge_flags & BGE_FLAG_BER_BUG) + brgphy_fixup_ber_bug(sc); + if (bge_sc->bge_flags & BGE_FLAG_JITTER_BUG) + brgphy_fixup_jitter_bug(sc); } else if (bce_sc) { /* Set or clear jumbo frame settings in the PHY. */ if (ifp->if_mtu > ETHER_MAX_LEN) { Index: sys/dev/mii/miidevs =================================================================== RCS file: /home/ncvs/src/sys/dev/mii/miidevs,v retrieving revision 1.38 diff -u -r1.38 miidevs --- sys/dev/mii/miidevs 5 Jan 2007 01:46:26 -0000 1.38 +++ sys/dev/mii/miidevs 9 Jan 2007 02:50:27 -0000 @@ -131,6 +131,7 @@ model xxBROADCOM BCM5780 0x0035 BCM5780 10/100/1000baseTX PHY model xxBROADCOM BCM5706C 0x0015 BCM5706C 10/100/1000baseTX PHY model xxBROADCOM BCM5708C 0x0036 BCM5708C 10/100/1000baseTX PHY +model xxBROADCOM_ALT1 BCM5787 0x000e BCM5787 10/100/1000baseTX PHY /* Cicada Semiconductor PHYs (now owned by Vitesse?) */ model CICADA CS8201 0x0001 Cicada CS8201 10/100/1000TX PHY