Module Name:    src
Committed By:   martin
Date:           Sat Jan 29 16:59:32 UTC 2022

Modified Files:
        src/sys/dev/mii [netbsd-9]: makphy.c makphyvar.h

Log Message:
Pull up the following revisions (all via patch), requested by msaitoh
in ticket #1410:

        sys/dev/mii/makphy.c                            1.67,1.69-1.72
        sys/dev/mii/makphyvar.h                         1.3-1.4

- Add I347-AT4 support.
- Add three workarounds for QEMU e1000:
  - QEMU sets BMSR_EXTSTAT but the access to register 15 fails.
    Set EXTSR_1000TFDX and EXTSR_1000THDX if the access failed in the
    attach function. It's just a cosmetic change.
  - Marvell 88E1[01]11 have the Fiber/Copper auto selection feature,
    but QEMU doesn't implement it. If the register access failed,
    the media is regarded as copper only. It's just a cosmetic change.
  - QEMU provides the PHY specific status register at 0x11 but the
    link indication bit (PSSR_LINK) is always 1. It causes
    "virsh domif-setlink xxx yyy down" doesn't work. To avoid this
    problem, read the BMSR and check the BMSR_LINK bit. Add
    MAKPHY_QUIRK_PSSR_LINK bit for this quirk. Set it if MII_EXTSR
    doesn't exist because it's one of the case of QEMU.
- Reduce the number of access to the ESSR register. One of the reason
  is that the register is not implemented on QEMU. Another reason is
  that it's not required to access the register if the device is in
  the copper only mode.


To generate a diff of this commit:
cvs rdiff -u -r1.60.2.3 -r1.60.2.4 src/sys/dev/mii/makphy.c
cvs rdiff -u -r1.2 -r1.2.6.1 src/sys/dev/mii/makphyvar.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/dev/mii/makphy.c
diff -u src/sys/dev/mii/makphy.c:1.60.2.3 src/sys/dev/mii/makphy.c:1.60.2.4
--- src/sys/dev/mii/makphy.c:1.60.2.3	Sat Jan 29 16:54:42 2022
+++ src/sys/dev/mii/makphy.c	Sat Jan 29 16:59:31 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: makphy.c,v 1.60.2.3 2022/01/29 16:54:42 martin Exp $	*/
+/*	$NetBSD: makphy.c,v 1.60.2.4 2022/01/29 16:59:31 martin 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.60.2.3 2022/01/29 16:54:42 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: makphy.c,v 1.60.2.4 2022/01/29 16:59:31 martin Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -117,6 +117,7 @@ static const struct mii_phydesc makphys[
 	MII_PHY_DESC(xxMARVELL, E3016),
 	MII_PHY_DESC(xxMARVELL, E3082),
 	MII_PHY_DESC(xxMARVELL, PHYG65G),
+	MII_PHY_DESC(xxMARVELL, I347),
 	MII_PHY_END,
 };
 
@@ -159,6 +160,7 @@ makphyattach(device_t parent, device_t s
 	struct makphy_softc *maksc = (struct makphy_softc *)sc;
 	const char *name;
 	uint16_t reg, model;
+	int rv;
 
 	mpd = mii_phy_match(ma, makphys);
 	aprint_naive(": Media interface\n");
@@ -205,8 +207,22 @@ page0:
 
 	PHY_READ(sc, MII_BMSR, &sc->mii_capabilities);
 	sc->mii_capabilities &= ma->mii_capmask;
-	if (sc->mii_capabilities & BMSR_EXTSTAT)
-		PHY_READ(sc, MII_EXTSR, &sc->mii_extcapabilities);
+	if (sc->mii_capabilities & BMSR_EXTSTAT) {
+		rv = PHY_READ(sc, MII_EXTSR, &sc->mii_extcapabilities);
+		if (rv != 0) {
+			aprint_verbose_dev(self, "Failed to read EXTSR. "
+			    "Are you an emulator?. "
+			    "Regard as 1000BASE-T.\n");
+			sc->mii_extcapabilities
+			    |= EXTSR_1000TFDX | EXTSR_1000THDX;
+
+			/*
+			 * Also assume it doesn't support PSSR_LINK bit.
+			 * It's for QEMU.
+			 */
+			maksc->sc_flags |= MAKPHY_QUIRK_PSSR_LINK;
+		}
+	}
 
 	if (((sc->mii_extcapabilities & (EXTSR_1000TFDX | EXTSR_1000THDX))
 		!= 0)
@@ -219,8 +235,18 @@ page0:
 		case MII_MODEL_xxMARVELL_E1011:
 		case MII_MODEL_xxMARVELL_E1111:
 			/* These devices have ESSR register */
-			PHY_READ(sc, MAKPHY_ESSR, &reg);
-			if ((reg & ESSR_AUTOSEL_DISABLE) != 0) {
+			rv = PHY_READ(sc, MAKPHY_ESSR, &reg);
+			if (rv != 0) {
+				/*
+				 * XXX Emulator (e.g qemu) may not implement
+				 * the ESSR register. If so, regard as copper
+				 * media.
+				 */
+				copperonly = true;
+				aprint_verbose_dev(self, "Failed to access "
+				    "ESSR. Are you an emulator? Regard as "
+				    "copper only media.\n");
+			} else if ((reg & ESSR_AUTOSEL_DISABLE) != 0) {
 				switch (reg & ESSR_HWCFG_MODE) {
 				case ESSR_RTBI_FIBER:
 				case ESSR_RGMII_FIBER:
@@ -238,7 +264,8 @@ page0:
 				default:
 					break;
 				}
-			}
+			} else
+				maksc->sc_flags |= MAKPHY_F_FICO_AUTOSEL;
 			break;
 		default:
 			break;
@@ -418,6 +445,7 @@ makphy_service(struct mii_softc *sc, str
 static void
 makphy_status(struct mii_softc *sc)
 {
+	struct makphy_softc *maksc = (struct makphy_softc *)sc;
 	struct mii_data *mii = sc->mii_pdata;
 	uint16_t bmcr, gsr, pssr, essr;
 
@@ -428,6 +456,23 @@ makphy_status(struct mii_softc *sc)
 	/* XXX FIXME: Use different page for Fiber on newer chips */
 	PHY_READ(sc, MAKPHY_PSSR, &pssr);
 
+	if ((maksc->sc_flags & MAKPHY_QUIRK_PSSR_LINK) != 0) {
+		uint16_t bmsr;
+
+		/*
+		 * QEMU e1000 driver has the PSSR register but it doesn't
+		 * support the PSSR_LINK bit well. It always returns 1.
+		 * To avoid this problem, use the BMSR_LINK bit. It's not
+		 * required to read it twice as real device because it's not
+		 * latched.
+		 */
+		PHY_READ(sc, MII_BMSR, &bmsr);
+		if (bmsr & BMSR_LINK)
+			pssr |= MAKPHY_PSSR_LINK;
+		else
+			pssr &= ~MAKPHY_PSSR_LINK;
+	}
+
 	if (pssr & MAKPHY_PSSR_LINK)
 		mii->mii_media_status |= IFM_ACTIVE;
 
@@ -466,14 +511,17 @@ makphy_status(struct mii_softc *sc)
 		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)
+		if ((maksc->sc_flags & MAKPHY_F_FICO_AUTOSEL) != 0) {
+			/* Fiber/Copper auto select mode */
+			PHY_READ(sc, MAKPHY_ESSR, &essr);
+			if ((essr & ESSR_FIBER_LINK) == 0)
+				goto copper;
+			else {
+				/* Regard as 1000BASE-SX */
+				mii->mii_media_active |= IFM_1000_SX;
+			}
+		} else
 			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 */
 

Index: src/sys/dev/mii/makphyvar.h
diff -u src/sys/dev/mii/makphyvar.h:1.2 src/sys/dev/mii/makphyvar.h:1.2.6.1
--- src/sys/dev/mii/makphyvar.h:1.2	Mon Mar 25 06:17:56 2019
+++ src/sys/dev/mii/makphyvar.h	Sat Jan 29 16:59:31 2022
@@ -1,4 +1,4 @@
-/* $NetBSD: makphyvar.h,v 1.2 2019/03/25 06:17:56 msaitoh Exp $ */
+/* $NetBSD: makphyvar.h,v 1.2.6.1 2022/01/29 16:59:31 martin Exp $ */
 
 /*-
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -37,6 +37,11 @@ struct makphy_softc {
 	uint32_t sc_flags;
 };
 
-#define MAKPHY_F_I210	__BIT(0)	/* Identify I210 (mii_model == 0) */
+#define MAKPHY_F_I210		__BIT(0) /* Identify I210 (mii_model == 0) */
+#define MAKPHY_F_FICO_AUTOSEL	__BIT(1) /* Fiber/Copper autoselect mode */
+#define MAKPHY_QUIRK_PSSR_LINK	__BIT(2) /*
+					  * For emulator which doesn't support
+					  * PSSR_LINK (e.g. QEMU).
+					  */
 
 #endif /* _MII_MAKPHYVAR_H_ */

Reply via email to