Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev - Fix detection of BGEPHYF_FIBER_{MII|TBI}
details: https://anonhg.NetBSD.org/src/rev/58be8a5fcd7e
branches: trunk
changeset: 330023:58be8a5fcd7e
user: msaitoh <msaitoh%NetBSD.org@localhost>
date: Tue Jun 17 21:37:20 2014 +0000
description:
- Fix detection of BGEPHYF_FIBER_{MII|TBI}
- Add BCM5708S support in brgphy(4). The auto negotiation may have some bugs.
- Add 2500SX support (not tested).
- Fix bit definition of BRGPHY_MRBE_MSG_PG5_NP_T2 from FreeBSD.
diffstat:
sys/dev/mii/brgphy.c | 387 +++++++++++++++++++++++++++++++++++------------
sys/dev/mii/brgphyreg.h | 12 +-
sys/dev/pci/if_bge.c | 15 +-
sys/dev/pci/if_bnx.c | 6 +-
sys/dev/pci/if_bnxreg.h | 5 +-
5 files changed, 308 insertions(+), 117 deletions(-)
diffs (truncated from 671 to 300 lines):
diff -r f9a914eaff0d -r 58be8a5fcd7e sys/dev/mii/brgphy.c
--- a/sys/dev/mii/brgphy.c Tue Jun 17 19:33:20 2014 +0000
+++ b/sys/dev/mii/brgphy.c Tue Jun 17 21:37:20 2014 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: brgphy.c,v 1.70 2014/06/16 16:48:16 msaitoh Exp $ */
+/* $NetBSD: brgphy.c,v 1.71 2014/06/17 21:37:20 msaitoh 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.70 2014/06/16 16:48:16 msaitoh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: brgphy.c,v 1.71 2014/06/17 21:37:20 msaitoh Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -90,8 +90,10 @@
struct mii_softc sc_mii;
bool sc_isbge;
bool sc_isbnx;
- uint32_t sc_chipid; /* parent's chipid */
- uint32_t sc_phyflags; /* parent's phyflags */
+ uint32_t sc_chipid; /* parent's chipid */
+ uint32_t sc_phyflags; /* parent's phyflags */
+ uint32_t sc_shared_hwcfg; /* shared hw config */
+ uint32_t sc_port_hwcfg; /* port specific hw config */
};
CFATTACH_DECL3_NEW(brgphy, sizeof(struct brgphy_softc),
@@ -99,7 +101,10 @@
DVF_DETACH_SHUTDOWN);
static int brgphy_service(struct mii_softc *, struct mii_data *, int);
-static void brgphy_status(struct mii_softc *);
+static void brgphy_copper_status(struct mii_softc *);
+static void brgphy_fiber_status(struct mii_softc *);
+static void brgphy_5708s_status(struct mii_softc *);
+static void brgphy_5709s_status(struct mii_softc *);
static int brgphy_mii_phy_auto(struct mii_softc *);
static void brgphy_loop(struct mii_softc *);
static void brgphy_reset(struct mii_softc *);
@@ -116,8 +121,20 @@
static void brgphy_eth_wirespeed(struct mii_softc *);
-static const struct mii_phy_funcs brgphy_funcs = {
- brgphy_service, brgphy_status, brgphy_reset,
+static const struct mii_phy_funcs brgphy_copper_funcs = {
+ brgphy_service, brgphy_copper_status, brgphy_reset,
+};
+
+static const struct mii_phy_funcs brgphy_fiber_funcs = {
+ brgphy_service, brgphy_fiber_status, brgphy_reset,
+};
+
+static const struct mii_phy_funcs brgphy_5708s_funcs = {
+ brgphy_service, brgphy_5708s_status, brgphy_reset,
+};
+
+static const struct mii_phy_funcs brgphy_5709s_funcs = {
+ brgphy_service, brgphy_5709s_status, brgphy_reset,
};
static const struct mii_phydesc brgphys[] = {
@@ -178,6 +195,9 @@
{ MII_OUI_BROADCOM2, MII_MODEL_BROADCOM2_BCM5482,
MII_STR_BROADCOM2_BCM5482 },
+ { MII_OUI_BROADCOM2, MII_MODEL_BROADCOM2_BCM5708S,
+ MII_STR_BROADCOM2_BCM5708S },
+
{ MII_OUI_BROADCOM2, MII_MODEL_BROADCOM2_BCM5709C,
MII_STR_BROADCOM2_BCM5709C },
@@ -264,7 +284,6 @@
sc->mii_pdata = mii;
sc->mii_flags = ma->mii_flags;
sc->mii_anegticks = MII_ANEGTICKS;
- sc->mii_funcs = &brgphy_funcs;
if (device_is_a(parent, "bge"))
bsc->sc_isbge = true;
@@ -281,10 +300,29 @@
aprint_error_dev(self, "failed to get chipid\n");
}
+ if (bsc->sc_isbnx) {
+ /* Currently, only bnx use sc_shared_hwcfg and sc_port_hwcfg */
+ if (!prop_dictionary_get_uint32(dict, "shared_hwcfg",
+ &bsc->sc_shared_hwcfg))
+ aprint_error_dev(self, "failed to get shared_hwcfg\n");
+ if (!prop_dictionary_get_uint32(dict, "port_hwcfg",
+ &bsc->sc_port_hwcfg))
+ aprint_error_dev(self, "failed to get port_hwcfg\n");
+ }
+
+ if (sc->mii_flags & MIIF_HAVEFIBER) {
+ if (_BNX_CHIP_NUM(bsc->sc_chipid) == BNX_CHIP_NUM_5708)
+ sc->mii_funcs = &brgphy_5708s_funcs;
+ else if (_BNX_CHIP_NUM(bsc->sc_chipid) == BNX_CHIP_NUM_5709)
+ sc->mii_funcs = &brgphy_5709s_funcs;
+ else
+ sc->mii_funcs = &brgphy_fiber_funcs;
+ } else
+ sc->mii_funcs = &brgphy_copper_funcs;
+
PHY_RESET(sc);
- sc->mii_capabilities =
- PHY_READ(sc, MII_BMSR) & ma->mii_capmask;
+ sc->mii_capabilities = PHY_READ(sc, MII_BMSR) & ma->mii_capmask;
if (sc->mii_capabilities & BMSR_EXTSTAT)
sc->mii_extcapabilities = PHY_READ(sc, MII_EXTSR);
@@ -363,6 +401,10 @@
case IFM_AUTO:
(void) brgphy_mii_phy_auto(sc);
break;
+ case IFM_2500_SX:
+ speed = BRGPHY_5708S_BMCR_2500;
+ goto setit;
+ case IFM_1000_SX:
case IFM_1000_T:
speed = BMCR_S1000;
goto setit;
@@ -383,7 +425,9 @@
PHY_WRITE(sc, MII_ANAR, ANAR_CSMA);
PHY_WRITE(sc, MII_BMCR, speed);
- if (IFM_SUBTYPE(ife->ifm_media) != IFM_1000_T)
+ if ((IFM_SUBTYPE(ife->ifm_media) != IFM_1000_T) &&
+ (IFM_SUBTYPE(ife->ifm_media) != IFM_1000_SX) &&
+ (IFM_SUBTYPE(ife->ifm_media) != IFM_2500_SX))
break;
PHY_WRITE(sc, MII_100T2CR, gig);
@@ -492,7 +536,7 @@
}
static void
-brgphy_status(struct mii_softc *sc)
+brgphy_copper_status(struct mii_softc *sc)
{
struct mii_data *mii = sc->mii_pdata;
struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
@@ -526,85 +570,46 @@
return;
}
- if ((sc->mii_mpd_oui == MII_OUI_BROADCOM2)
- && (sc->mii_mpd_model == MII_MODEL_BROADCOM2_BCM5709S)) {
- /*
- * 5709S has its own general purpose status registers
- */
- PHY_WRITE(sc, BRGPHY_BLOCK_ADDR,
- BRGPHY_BLOCK_ADDR_GP_STATUS);
-
- auxsts = PHY_READ(sc, BRGPHY_GP_STATUS_TOP_ANEG_STATUS);
-
- PHY_WRITE(sc, BRGPHY_BLOCK_ADDR,
- BRGPHY_BLOCK_ADDR_COMBO_IEEE0);
+ auxsts = PHY_READ(sc, BRGPHY_MII_AUXSTS);
- switch (auxsts & BRGPHY_GP_STATUS_TOP_ANEG_SPEED_MASK) {
- case BRGPHY_GP_STATUS_TOP_ANEG_SPEED_10:
- mii->mii_media_active |= IFM_10_FL;
- break;
- case BRGPHY_GP_STATUS_TOP_ANEG_SPEED_100:
- mii->mii_media_active |= IFM_100_FX;
- break;
- case BRGPHY_GP_STATUS_TOP_ANEG_SPEED_1G:
- mii->mii_media_active |= IFM_1000_SX;
- break;
- case BRGPHY_GP_STATUS_TOP_ANEG_SPEED_25G:
- mii->mii_media_active |= IFM_2500_SX;
- break;
- default:
- mii->mii_media_active |= IFM_NONE;
- mii->mii_media_status = 0;
- break;
- }
+ switch (auxsts & BRGPHY_AUXSTS_AN_RES) {
+ case BRGPHY_RES_1000FD:
+ mii->mii_media_active |= IFM_1000_T | IFM_FDX;
+ gtsr = PHY_READ(sc, MII_100T2SR);
+ if (gtsr & GTSR_MS_RES)
+ mii->mii_media_active |= IFM_ETH_MASTER;
+ break;
- if (auxsts & BRGPHY_GP_STATUS_TOP_ANEG_FDX)
- mii->mii_media_active |= IFM_FDX;
- else
- mii->mii_media_active |= IFM_HDX;
-
- } else {
- auxsts = PHY_READ(sc, BRGPHY_MII_AUXSTS);
+ case BRGPHY_RES_1000HD:
+ mii->mii_media_active |= IFM_1000_T | IFM_HDX;
+ gtsr = PHY_READ(sc, MII_100T2SR);
+ if (gtsr & GTSR_MS_RES)
+ mii->mii_media_active |= IFM_ETH_MASTER;
+ break;
- switch (auxsts & BRGPHY_AUXSTS_AN_RES) {
- case BRGPHY_RES_1000FD:
- mii->mii_media_active |= IFM_1000_T | IFM_FDX;
- gtsr = PHY_READ(sc, MII_100T2SR);
- if (gtsr & GTSR_MS_RES)
- mii->mii_media_active |= IFM_ETH_MASTER;
- break;
+ case BRGPHY_RES_100FD:
+ mii->mii_media_active |= IFM_100_TX | IFM_FDX;
+ break;
- case BRGPHY_RES_1000HD:
- mii->mii_media_active |= IFM_1000_T | IFM_HDX;
- gtsr = PHY_READ(sc, MII_100T2SR);
- if (gtsr & GTSR_MS_RES)
- mii->mii_media_active |= IFM_ETH_MASTER;
- break;
+ case BRGPHY_RES_100T4:
+ mii->mii_media_active |= IFM_100_T4 | IFM_HDX;
+ break;
- case BRGPHY_RES_100FD:
- mii->mii_media_active |= IFM_100_TX | IFM_FDX;
- break;
+ case BRGPHY_RES_100HD:
+ mii->mii_media_active |= IFM_100_TX | IFM_HDX;
+ break;
- case BRGPHY_RES_100T4:
- mii->mii_media_active |= IFM_100_T4 | IFM_HDX;
- break;
-
- case BRGPHY_RES_100HD:
- mii->mii_media_active |= IFM_100_TX | IFM_HDX;
- break;
+ case BRGPHY_RES_10FD:
+ mii->mii_media_active |= IFM_10_T | IFM_FDX;
+ break;
- case BRGPHY_RES_10FD:
- mii->mii_media_active |= IFM_10_T | IFM_FDX;
- break;
+ case BRGPHY_RES_10HD:
+ mii->mii_media_active |= IFM_10_T | IFM_HDX;
+ break;
- case BRGPHY_RES_10HD:
- mii->mii_media_active |= IFM_10_T | IFM_HDX;
- break;
-
- default:
- mii->mii_media_active |= IFM_NONE;
- mii->mii_media_status = 0;
- }
+ default:
+ mii->mii_media_active |= IFM_NONE;
+ mii->mii_media_status = 0;
}
if (mii->mii_media_active & IFM_FDX)
@@ -614,6 +619,188 @@
mii->mii_media_active = ife->ifm_media;
}
+void
+brgphy_fiber_status(struct mii_softc *sc)
+{
+ struct mii_data *mii = sc->mii_pdata;
+ struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
+ int bmcr, bmsr;
+
+ mii->mii_media_status = IFM_AVALID;
+ mii->mii_media_active = IFM_ETHER;
+
+ bmsr = PHY_READ(sc, MII_BMSR) | PHY_READ(sc, MII_BMSR);
+ if (bmsr & BMSR_LINK)
+ mii->mii_media_status |= IFM_ACTIVE;
+
+ bmcr = PHY_READ(sc, MII_BMCR);
+ if (bmcr & BMCR_LOOP)
+ mii->mii_media_active |= IFM_LOOP;
+
+ if (bmcr & BMCR_AUTOEN) {
+ int val;
+
+ if ((bmsr & BMSR_ACOMP) == 0) {
+ /* Erg, still trying, I guess... */
+ mii->mii_media_active |= IFM_NONE;
+ return;
+ }
+
+ mii->mii_media_active |= IFM_1000_SX;
+
+ val = PHY_READ(sc, MII_ANAR) &
+ PHY_READ(sc, MII_ANLPAR);
Home |
Main Index |
Thread Index |
Old Index