Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev Fix BCM5709 PHY detection for ethernet PHYs (the Ser...



details:   https://anonhg.NetBSD.org/src/rev/7cc7ad26fbe1
branches:  trunk
changeset: 764737:7cc7ad26fbe1
user:      jym <jym%NetBSD.org@localhost>
date:      Mon May 02 09:03:10 2011 +0000

description:
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!)

diffstat:

 sys/dev/mii/brgphy.c    |  73 ++++++++++++++++++++++++++++++++----------------
 sys/dev/pci/if_bge.c    |   7 ++--
 sys/dev/pci/if_bnx.c    |   7 ++--
 sys/dev/pci/if_bnxreg.h |   8 +++--
 4 files changed, 62 insertions(+), 33 deletions(-)

diffs (261 lines):

diff -r ac1ba46e68c9 -r 7cc7ad26fbe1 sys/dev/mii/brgphy.c
--- a/sys/dev/mii/brgphy.c      Mon May 02 08:32:21 2011 +0000
+++ b/sys/dev/mii/brgphy.c      Mon May 02 09:03:10 2011 +0000
@@ -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 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_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 @@
                sc->mii_extcapabilities = PHY_READ(sc, MII_EXTSR);
 
 
-       if (device_is_a(parent, "bge")) {
+       if (device_is_a(parent, "bge"))
                bsc->sc_isbge = true;
+       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_bge_flags))
-                       aprint_error_dev(self, "failed to get phyflags");
-       } else if (device_is_a(parent, "bnx")) {
-               bsc->sc_isbnx = true;
-               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 @@
                                 * 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 @@
        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 @@
 
                                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 @@
                                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_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 @@
                         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);
@@ -955,6 +968,18 @@
 }
 
 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)
 {
        u_int32_t val;
diff -r ac1ba46e68c9 -r 7cc7ad26fbe1 sys/dev/pci/if_bge.c
--- a/sys/dev/pci/if_bge.c      Mon May 02 08:32:21 2011 +0000
+++ b/sys/dev/pci/if_bge.c      Mon May 02 09:03:10 2011 +0000
@@ -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 @@
                    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,
diff -r ac1ba46e68c9 -r 7cc7ad26fbe1 sys/dev/pci/if_bnx.c
--- a/sys/dev/pci/if_bnx.c      Mon May 02 08:32:21 2011 +0000
+++ b/sys/dev/pci/if_bnx.c      Mon May 02 09:03:10 2011 +0000
@@ -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 @@
        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;
diff -r ac1ba46e68c9 -r 7cc7ad26fbe1 sys/dev/pci/if_bnxreg.h
--- a/sys/dev/pci/if_bnxreg.h   Mon May 02 08:32:21 2011 +0000
+++ b/sys/dev/pci/if_bnxreg.h   Mon May 02 09:03:10 2011 +0000
@@ -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



Home | Main Index | Thread Index | Old Index