summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorjkim <jkim@FreeBSD.org>2007-01-15 21:43:43 +0000
committerjkim <jkim@FreeBSD.org>2007-01-15 21:43:43 +0000
commitffb38d52f7b3579a1efb44a06318b0faa572bcc8 (patch)
tree95041596e03942ebeb6200154a4e90f1599203b3 /sys
parent9ca9d354d98eb12e0acd1619a9545f682a7ec672 (diff)
downloadFreeBSD-src-ffb38d52f7b3579a1efb44a06318b0faa572bcc8.zip
FreeBSD-src-ffb38d52f7b3579a1efb44a06318b0faa572bcc8.tar.gz
- Fix BCM5754 support found in Dell PowerEdge SC440.
- Move some PHY bug detections from brgphy.c to if_bge.c. - Do not penalize working PHYs. - Re-arrange bge_flags roughly by their categories. - Fix minor style(9) nits. PR: kern/107257 Obtained from: OpenBSD Tested by: Mike Hibler <mike at flux dot utah dot edu>
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/bge/if_bge.c25
-rw-r--r--sys/dev/bge/if_bgereg.h30
-rw-r--r--sys/dev/mii/brgphy.c70
-rw-r--r--sys/dev/mii/miidevs1
4 files changed, 85 insertions, 41 deletions
diff --git a/sys/dev/bge/if_bge.c b/sys/dev/bge/if_bge.c
index a036cfe..f1ba0a4 100644
--- a/sys/dev/bge/if_bge.c
+++ b/sys/dev/bge/if_bge.c
@@ -1686,7 +1686,7 @@ bge_probe(device_t dev)
br != NULL ? "" : "unknown ", id >> 16);
device_set_desc_copy(dev, buf);
if (pci_get_subvendor(dev) == DELL_VENDORID)
- sc->bge_flags |= BGE_FLAG_NO3LED;
+ sc->bge_flags |= BGE_FLAG_NO_3LED;
return (0);
}
t++;
@@ -2197,25 +2197,36 @@ bge_attach(device_t dev)
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.
*/
@@ -4190,7 +4201,7 @@ bge_sysctl_debug_info(SYSCTL_HANDLER_ARGS)
printf(" - PCI-X Bus\n");
if (sc->bge_flags & BGE_FLAG_PCIE)
printf(" - PCI Express Bus\n");
- if (sc->bge_flags & BGE_FLAG_NO3LED)
+ if (sc->bge_flags & BGE_FLAG_NO_3LED)
printf(" - No 3 LEDs\n");
if (sc->bge_flags & BGE_FLAG_RX_ALIGNBUG)
printf(" - RX Alignment Bug\n");
diff --git a/sys/dev/bge/if_bgereg.h b/sys/dev/bge/if_bgereg.h
index 3dd9106..80a04f6 100644
--- a/sys/dev/bge/if_bgereg.h
+++ b/sys/dev/bge/if_bgereg.h
@@ -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
@@ -2445,18 +2448,21 @@ struct bge_softc {
struct resource *bge_res;
struct ifmedia bge_ifmedia; /* TBI media info */
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_PCIX 0x00000010
-#define BGE_FLAG_PCIE 0x00000020
-#define BGE_FLAG_JUMBO 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_TBI 0x00000001
+#define BGE_FLAG_JUMBO 0x00000002
+#define BGE_FLAG_MSI 0x00000100
+#define BGE_FLAG_PCIX 0x00000200
+#define BGE_FLAG_PCIE 0x00000400
+#define BGE_FLAG_5700_FAMILY 0x00001000
+#define BGE_FLAG_5705_PLUS 0x00002000
+#define BGE_FLAG_5714_FAMILY 0x00004000
+#define BGE_FLAG_575X_PLUS 0x00008000
+#define BGE_FLAG_RX_ALIGNBUG 0x00100000
+#define BGE_FLAG_NO_3LED 0x00200000
+#define BGE_FLAG_ADC_BUG 0x00400000
+#define BGE_FLAG_5704_A0_BUG 0x00800000
+#define BGE_FLAG_JITTER_BUG 0x01000000
+#define BGE_FLAG_BER_BUG 0x02000000
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 3feae31..8c44ea5 100644
--- a/sys/dev/mii/brgphy.c
+++ b/sys/dev/mii/brgphy.c
@@ -93,9 +93,12 @@ static void brgphy_reset(struct mii_softc *);
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 @@ static const struct mii_phydesc brgphys[] = {
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 @@ brgphy_attach(device_t dev)
#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 @@ brgphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd)
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 @@ bcm5411_load_dspcode(struct mii_softc *sc)
}
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 @@ bcm5703_load_dspcode(struct mii_softc *sc)
}
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 @@ bcm5704_load_dspcode(struct mii_softc *sc)
}
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 @@ bcm5750_load_dspcode(struct mii_softc *sc)
}
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 @@ brgphy_reset(struct mii_softc *sc)
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;
@@ -634,11 +650,21 @@ brgphy_reset(struct mii_softc *sc)
PHY_WRITE(sc, BRGPHY_MII_AUXCTL, val | (1 << 15) | (1 << 4));
/* Enable Link LED on Dell boxes */
- if (bge_sc->bge_flags & BGE_FLAG_NO3LED) {
+ if (bge_sc->bge_flags & BGE_FLAG_NO_3LED) {
PHY_WRITE(sc, BRGPHY_MII_PHY_EXTCTL,
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) {
diff --git a/sys/dev/mii/miidevs b/sys/dev/mii/miidevs
index 8e6fd0d..ca3fb3f 100644
--- a/sys/dev/mii/miidevs
+++ b/sys/dev/mii/miidevs
@@ -131,6 +131,7 @@ model xxBROADCOM BCM5714 0x0034 BCM5714 10/100/1000baseTX PHY
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
OpenPOWER on IntegriCloud