⬢ DragonFlyBSD Kernel Audit
DF-5080 / fix.diff
← back to finding ↓ download raw
--- sys/dev/netif/mii_layer/nsgphy.c
+++ sys/dev/netif/mii_layer/nsgphy.c
@@ -250,11 +250,24 @@
 		}
 		anlpar = PHY_READ(sc, NSGPHY_MII_ANLPAR);
 		gstat = PHY_READ(sc, NSGPHY_MII_1000STS);
-		if (gstat & NSGPHY_1000STS_LPFD)
+		/*
+		 * Do not decode 1000baseT from the link-partner capability
+		 * bits while the master/slave exchange is unresolved, and
+		 * never on a master/slave fault: LPFD/LPHD reflect partner
+		 * ability even when no 1000Mbps link exists.
+		 */
+		if (gstat & NSGPHY_1000STS_MSF) {
+			mii->mii_media_active |= IFM_NONE;
+			return;
+		} else if (gstat & NSGPHY_1000STS_LPFD) {
 			mii->mii_media_active |= IFM_1000_T | IFM_FDX;
-		else if (gstat & NSGPHY_1000STS_LPHD)
+			if (gstat & NSGPHY_1000STS_MSR)
+				mii->mii_media_active |= IFM_ETH_MASTER;
+		} else if (gstat & NSGPHY_1000STS_LPHD) {
 			mii->mii_media_active |= IFM_1000_T | IFM_HDX;
-		else if (anlpar & NSGPHY_ANLPAR_100T4)
+			if (gstat & NSGPHY_1000STS_MSR)
+				mii->mii_media_active |= IFM_ETH_MASTER;
+		} else if (anlpar & NSGPHY_ANLPAR_100T4)
 			mii->mii_media_active |= IFM_100_T4;
 		else if (anlpar & NSGPHY_ANLPAR_100FDX)
 			mii->mii_media_active |= IFM_100_TX|IFM_FDX;