diff options
| author | msaitoh <msaitoh@NetBSD.org> | 2019-12-12 09:25:37 +0000 |
|---|---|---|
| committer | msaitoh <msaitoh@NetBSD.org> | 2019-12-12 09:25:37 +0000 |
| commit | 667811b979c4a31ee69f4a63ea9ff1d76c4638ed (patch) | |
| tree | b0a7c686f22b9ef210d7e6935448ca87bcac64a3 /sys/dev | |
| parent | f97c381ce74bbc6d8977c259af28bd4d3c7503bc (diff) | |
- Remove ESSR_FIBER_LINK bit check in makphyattach(). This bit is valid only
when the link is up, so it's not good to check in the attach function.
- There is an environment that both copper and fiber bits are set in EXTSR
but it support copper only. To resolve this problem, check the ESSR
register's HWCFG_MODE bit and drop unsupported bits.
- If the chip is in Fiber/Copper auto select mode, check which media is
selected. Currently, the code supports 88E1011, 88E1111 and 88E1112 only.
To support other chips documents are required.
Diffstat (limited to 'sys/dev')
| -rw-r--r-- | sys/dev/mii/makphy.c | 106 | ||||
| -rw-r--r-- | sys/dev/mii/makphyreg.h | 35 |
2 files changed, 113 insertions, 28 deletions
diff --git a/sys/dev/mii/makphy.c b/sys/dev/mii/makphy.c index 5aa262824ba..b2f9f4bc7c2 100644 --- a/sys/dev/mii/makphy.c +++ b/sys/dev/mii/makphy.c @@ -1,4 +1,4 @@ -/* $NetBSD: makphy.c,v 1.62 2019/11/27 10:19:20 msaitoh Exp $ */ +/* $NetBSD: makphy.c,v 1.63 2019/12/12 09:25:37 msaitoh Exp $ */ /*- * Copyright (c) 1998, 1999, 2000, 2001 The NetBSD Foundation, Inc. @@ -59,7 +59,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: makphy.c,v 1.62 2019/11/27 10:19:20 msaitoh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: makphy.c,v 1.63 2019/12/12 09:25:37 msaitoh Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -200,21 +200,6 @@ page0: break; } - switch (model) { - case MII_MODEL_xxMARVELL_E1011: - case MII_MODEL_xxMARVELL_E1112: - if (PHY_READ(sc, MAKPHY_ESSR, ®) != 0) { - aprint_verbose_dev(self, - "Failed to read MAKPHY_ESSR\n"); - break; - } - if (reg & ESSR_FIBER_LINK) - sc->mii_flags |= MIIF_HAVEFIBER; - break; - default: - break; - } - PHY_RESET(sc); PHY_READ(sc, MII_BMSR, &sc->mii_capabilities); @@ -222,6 +207,54 @@ page0: if (sc->mii_capabilities & BMSR_EXTSTAT) PHY_READ(sc, MII_EXTSR, &sc->mii_extcapabilities); + if (((sc->mii_extcapabilities & (EXTSR_1000TFDX | EXTSR_1000THDX)) + != 0) + && ((sc->mii_extcapabilities & (EXTSR_1000XFDX | EXTSR_1000XHDX)) + != 0)) { + bool fiberonly = false, copperonly = false; + + /* Both copper and fiber is set. check MODE[] */ + switch (sc->mii_mpd_model) { + case MII_MODEL_xxMARVELL_E1011: + case MII_MODEL_xxMARVELL_E1111: + /* These devices have ESSR register */ + PHY_READ(sc, MAKPHY_ESSR, ®); + if ((reg & ESSR_AUTOSEL_DISABLE) != 0) { + switch (reg & ESSR_HWCFG_MODE) { + case ESSR_RTBI_FIBER: + case ESSR_RGMII_FIBER: + case ESSR_RGMII_SGMII: /* right? */ + case ESSR_TBI_FIBER: + case ESSR_GMII_FIBER: + fiberonly = true; + break; + case ESSR_SGMII_WC_COPPER: + case ESSR_SGMII_WOC_COPPER: + case ESSR_RTBI_COPPER: + case ESSR_RGMII_COPPER: + case ESSR_GMII_COPPER: + copperonly = true; + default: + break; + } + } + break; + default: + break; + } + if (fiberonly || copperonly) + aprint_debug_dev(self, "both copper and fiber are set " + "but MODE[] is %s only.\n", + fiberonly ? "fiber" : "copper"); + if (fiberonly) + sc->mii_extcapabilities + &= ~(EXTSR_1000TFDX | EXTSR_1000THDX); + else if (copperonly) { + sc->mii_extcapabilities + &= ~(EXTSR_1000XFDX | EXTSR_1000XHDX); + sc->mii_flags &= ~MIIF_IS_1000X; + } + } mii_phy_add_media(sc); } @@ -378,7 +411,7 @@ static void makphy_status(struct mii_softc *sc) { struct mii_data *mii = sc->mii_pdata; - uint16_t bmcr, gsr, pssr; + uint16_t bmcr, gsr, pssr, essr; mii->mii_media_status = IFM_AVALID; mii->mii_media_active = IFM_ETHER; @@ -416,10 +449,45 @@ makphy_status(struct mii_softc *sc) } } - /* XXX FIXME: Use different page for Fiber on newer chips */ + /* + * XXX The following code support Fiber/Copper auto select mode + * only for 88E1011, 88E1111 and 88E1112. For other chips, the document + * is required. + */ if (sc->mii_flags & MIIF_IS_1000X) { + /* Not in Fiber/Copper auto select mode */ + mii->mii_media_active |= IFM_1000_SX; + } else if ((sc->mii_mpd_model == MII_MODEL_xxMARVELL_E1011) || + (sc->mii_mpd_model == MII_MODEL_xxMARVELL_E1111)) { + /* Fiber/Copper auto select mode */ + + PHY_READ(sc, MAKPHY_ESSR, &essr); + if ((essr & ESSR_FIBER_LINK) == 0) + goto copper; + + /* XXX Assume 1000BASE-SX only */ mii->mii_media_active |= IFM_1000_SX; + } else if (sc->mii_mpd_model == MII_MODEL_xxMARVELL_E1112) { + /* Fiber/Copper auto select mode */ + + PHY_READ(sc, MAKPHY_PSSR, &pssr); + if ((pssr & PSSR_RESOLUTION_FIBER) == 0) + goto copper; + + switch (PSSR_SPEED_get(pssr)) { + case SPEED_1000: + mii->mii_media_active |= IFM_1000_SX; + break; + case SPEED_100: + mii->mii_media_active |= IFM_100_FX; + break; + default: /* Undefined (reserved) value */ + mii->mii_media_active |= IFM_NONE; + mii->mii_media_status = 0; + return; + } } else { +copper: switch (PSSR_SPEED_get(pssr)) { case SPEED_1000: mii->mii_media_active |= IFM_1000_T; diff --git a/sys/dev/mii/makphyreg.h b/sys/dev/mii/makphyreg.h index 699c544064a..9d299a6857d 100644 --- a/sys/dev/mii/makphyreg.h +++ b/sys/dev/mii/makphyreg.h @@ -1,4 +1,4 @@ -/* $NetBSD: makphyreg.h,v 1.9 2018/12/28 06:20:32 msaitoh Exp $ */ +/* $NetBSD: makphyreg.h,v 1.10 2019/12/12 09:25:37 msaitoh Exp $ */ /*- * Copyright (c) 2001 The NetBSD Foundation, Inc. @@ -107,6 +107,12 @@ #define SPEED_1000 2 #define SPEED_reserved 3 +/* For 88E1112 */ +#define PSSR_RESOLUTION_FIBER (1U << 7) /* + * Fiber/Copper resolution + * 1 = Fiber, 0 = Copper + */ + #define MAKPHY_IE 0x12 /* Interrupt enable */ #define IE_JABBER (1U << 0) /* jabber indication */ #define IE_POL_CHANGED (1U << 1) /* polarity changed */ @@ -143,6 +149,7 @@ #define LEDCTRL_PULSE_STRCH(x) ((x) << 12) #define LEDCTRL_DISABLE (1U << 15) /* disable LED */ +/* For 88E1011, 88E1111 */ #define MAKPHY_ESSR 0x1b /* Extended PHY specific status */ #define ESSR_AUTOSEL_DISABLE 0x8000 /* Fiber/Copper autoselect disable */ #define ESSR_FIBER_LINK 0x2000 /* Fiber/Copper resolution */ @@ -153,13 +160,23 @@ #define ESSR_DTE_DROP_HYST 0x01e0 /* DTE detect status drop hysteresis */ #define ESSR_DTE_POWER 0x0010 #define ESSR_HWCFG_MODE 0x000f -#define ESSR_GMII_COPPER 0x000f -#define ESSR_GMII_FIBER 0x0007 -#define ESSR_RGMII_COPPER 0x000b -#define ESSR_RGMII_FIBER 0x0003 -#define ESSR_RGMII_SGMII 0x0006 -#define ESSR_TBI_COPPER 0x000d -#define ESSR_TBI_FIBER 0x0005 - +#define ESSR_SGMII_WC_COPPER 0x0000 /* SGMII w/ Clock w/ SGMII AN Copper */ +#define ESSR_RTBI_FIBER 0x0001 /* RTBI to Fiber */ +#define ESSR_RGMII_FIBER 0x0003 /* RGMII to Fiber */ +#define ESSR_SGMII_WOC_COPPER 0x0004 /* SGMII w/o Clock w/ SGMII AN Copp. */ +#define ESSR_TBI_FIBER 0x0005 /* TBI to Fiber */ +#define ESSR_RGMII_SGMII 0x0006 /* RGMII to SGMII */ +#define ESSR_GMII_FIBER 0x0007 /* GMII to Fiber */ +#define ESSR_SERIAL_WAN 0x0008 /* 88E1011: Serial w 1000KX AN */ +#define ESSR_GBIC 0x0008 /* 88E1111: GBIC */ +#define ESSR_RTBI_COPPER 0x0009 /* RTBI to Copper */ +#define ESSR_RGMII_COPPER 0x000b /* RGMII to Copper */ +#define ESSR_RGMII_AUTOSEL 0x000b /* RGMII with Auto-Selection */ +#define ESSR_SERIAL_WOAN 0x000c /* 88E1011: Serial w/o 1000KX AN */ +#define ESSR_1000X_WOAN 0x000c /* 88E1111: 1000X w/o AN Copper */ +#define ESSR_TBI_COPPER 0x000d /* TBI to Copper */ +#define ESSR_GMII_SGMII 0x000e /* GMII to SGMII */ +#define ESSR_GMII_COPPER 0x000f /* GMII to Copper */ +#define ESSR_GMII_AUTOSEL 0x000f /* GMII with Auto-Selection */ #endif /* _DEV_MII_MAKPHYREG_H_ */ |
