svn commit: r194414 - in stable/7/sys: . contrib/pf dev/mii

Pyun YongHyeon yongari at FreeBSD.org
Thu Jun 18 04:47:41 UTC 2009


Author: yongari
Date: Thu Jun 18 04:47:40 2009
New Revision: 194414
URL: http://svn.freebsd.org/changeset/base/194414

Log:
  MFC r192708-192711:
  
  r192708:
    Use mii_phy_add_media() and remove usage of local macro ADD. Also
    checks extended status register to see whether the PHY is fast
    ethernet or not. This removes a lot of checks for specific PHY
    models and it makes easy to add more PHYs to e1000phy(4).
  
    While I'm here remove setting mii_anegticks as it is set with
    mii_phy_add_media().
  
  r192709:
    Report current link state while auto-negotiation is in progress.
  
  r192710:
    Don't read unnecessary PHY registers. Speed/duplex resolution bit
    is valid only for auto-negotiation case so check the bit if we know
    auto-negotiation is active. While I'm here explicitly checks
    current speed with speed mask and set IFM_NONE if resolved speed
    is unknown.
  
  r192711:
    Do not ignore NEXT Page capability of auto-negotiation
    advertisement register. Some PHYs such as 88E3016 requires NEXT
    Page capability to establish valid link. Also set protocol selector
    field which is read only but it makes the intention clearer.

Modified:
  stable/7/sys/   (props changed)
  stable/7/sys/contrib/pf/   (props changed)
  stable/7/sys/dev/mii/e1000phy.c

Modified: stable/7/sys/dev/mii/e1000phy.c
==============================================================================
--- stable/7/sys/dev/mii/e1000phy.c	Thu Jun 18 04:42:47 2009	(r194413)
+++ stable/7/sys/dev/mii/e1000phy.c	Thu Jun 18 04:47:40 2009	(r194414)
@@ -128,7 +128,6 @@ e1000phy_attach(device_t dev)
 	struct mii_softc *sc;
 	struct mii_attach_args *ma;
 	struct mii_data *mii;
-	int fast_ether;
 
 	esc = device_get_softc(dev);
 	sc = &esc->mii_sc;
@@ -141,10 +140,8 @@ e1000phy_attach(device_t dev)
 	sc->mii_phy = ma->mii_phyno;
 	sc->mii_service = e1000phy_service;
 	sc->mii_pdata = mii;
-	sc->mii_anegticks = MII_ANEGTICKS_GIGE;
 	mii->mii_instance++;
 
-	fast_ether = 0;
 	esc->mii_model = MII_MODEL(ma->mii_id2);
 	switch (esc->mii_model) {
 	case MII_MODEL_MARVELL_E1011:
@@ -166,54 +163,16 @@ e1000phy_attach(device_t dev)
 		 */
 		PHY_WRITE(sc, E1000_EADR, 0);
 		break;
-	case MII_MODEL_MARVELL_E3082:
-		/* 88E3082 10/100 Fast Ethernet PHY. */
-		sc->mii_anegticks = MII_ANEGTICKS;
-		fast_ether = 1;
-		break;
 	}
 
 	e1000phy_reset(sc);
 
+	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);
 	device_printf(dev, " ");
-
-#define	ADD(m, c)	ifmedia_add(&mii->mii_media, (m), (c), NULL)
-	ADD(IFM_MAKEWORD(IFM_ETHER, IFM_NONE, 0, sc->mii_inst),
-	    E1000_CR_ISOLATE);
-	if ((sc->mii_flags & MIIF_HAVEFIBER) == 0) {
-		ADD(IFM_MAKEWORD(IFM_ETHER, IFM_10_T, 0, sc->mii_inst),
-		    E1000_CR_SPEED_10);
-		printf("10baseT, ");
-		ADD(IFM_MAKEWORD(IFM_ETHER, IFM_10_T, IFM_FDX, sc->mii_inst),
-		    E1000_CR_SPEED_10 | E1000_CR_FULL_DUPLEX);
-		printf("10baseT-FDX, ");
-		ADD(IFM_MAKEWORD(IFM_ETHER, IFM_100_TX, 0, sc->mii_inst),
-		    E1000_CR_SPEED_100);
-		printf("100baseTX, ");
-		ADD(IFM_MAKEWORD(IFM_ETHER, IFM_100_TX, IFM_FDX, sc->mii_inst),
-		    E1000_CR_SPEED_100 | E1000_CR_FULL_DUPLEX);
-		printf("100baseTX-FDX, ");
-		if (fast_ether == 0) {
-			/*
-			 * 1000BT-simplex not supported; driver must ignore
-			 * this entry, but it must be present in order to
-			 * manually set full-duplex.
-			 */
-			ADD(IFM_MAKEWORD(IFM_ETHER, IFM_1000_T, 0,
-			    sc->mii_inst), E1000_CR_SPEED_1000);
-			ADD(IFM_MAKEWORD(IFM_ETHER, IFM_1000_T, IFM_FDX,
-			    sc->mii_inst),
-			    E1000_CR_SPEED_1000 | E1000_CR_FULL_DUPLEX);
-			printf("1000baseTX-FDX, ");
-		}
-	} else {
-		ADD(IFM_MAKEWORD(IFM_ETHER, IFM_1000_SX, IFM_FDX, sc->mii_inst),
-		    E1000_CR_SPEED_1000 | E1000_CR_FULL_DUPLEX);
-		printf("1000baseSX-FDX, ");
-	}
-	ADD(IFM_MAKEWORD(IFM_ETHER, IFM_AUTO, 0, sc->mii_inst), 0);
-	printf("auto\n");
-#undef ADD
+	mii_phy_add_media(sc);
+	printf("\n");
 
 	MIIBUS_MEDIAINIT(sc->mii_dev);
 	return (0);
@@ -338,12 +297,14 @@ e1000phy_service(struct mii_softc *sc, s
 		speed = 0;
 		switch (IFM_SUBTYPE(ife->ifm_media)) {
 		case IFM_1000_T:
-			if (esc->mii_model == MII_MODEL_MARVELL_E3082)
+			if ((sc->mii_extcapabilities &
+			    (EXTSR_1000TFDX | EXTSR_1000THDX)) == 0)
 				return (EINVAL);
 			speed = E1000_CR_SPEED_1000;
 			break;
 		case IFM_1000_SX:
-			if (esc->mii_model == MII_MODEL_MARVELL_E3082)
+			if ((sc->mii_extcapabilities &
+			    (EXTSR_1000XFDX | EXTSR_1000XHDX)) == 0)
 				return (EINVAL);
 			speed = E1000_CR_SPEED_1000;
 			break;
@@ -389,7 +350,8 @@ e1000phy_service(struct mii_softc *sc, s
 				PHY_WRITE(sc, E1000_1GCR, gig |
 				    E1000_1GCR_MS_ENABLE);
 		} else {
-			if (esc->mii_model != MII_MODEL_MARVELL_E3082)
+			if ((sc->mii_extcapabilities &
+			    (EXTSR_1000TFDX | EXTSR_1000THDX)) != 0)
 				PHY_WRITE(sc, E1000_1GCR, 0);
 		}
 		PHY_WRITE(sc, E1000_AR, E1000_AR_SELECTOR_FIELD);
@@ -431,7 +393,7 @@ done:
 		if (sc->mii_ticks++ == 0)
 			break;
 		if (sc->mii_ticks <= sc->mii_anegticks)
-			return (0);
+			break;
 
 		sc->mii_ticks = 0;
 		e1000phy_reset(sc);
@@ -451,18 +413,14 @@ static void
 e1000phy_status(struct mii_softc *sc)
 {
 	struct mii_data *mii = sc->mii_pdata;
-	int bmsr, bmcr, esr, gsr, ssr, isr, ar, lpar;
+	int bmcr, bmsr, gsr, ssr, ar, lpar;
 
 	mii->mii_media_status = IFM_AVALID;
 	mii->mii_media_active = IFM_ETHER;
 
 	bmsr = PHY_READ(sc, E1000_SR) | PHY_READ(sc, E1000_SR);
-	esr = PHY_READ(sc, E1000_ESR);
 	bmcr = PHY_READ(sc, E1000_CR);
 	ssr = PHY_READ(sc, E1000_SSR);
-	isr = PHY_READ(sc, E1000_ISR);
-	ar = PHY_READ(sc, E1000_AR);
-	lpar = PHY_READ(sc, E1000_LPAR);
 
 	if (bmsr & E1000_SR_LINK_STATUS)
 		mii->mii_media_status |= IFM_ACTIVE;
@@ -470,22 +428,28 @@ e1000phy_status(struct mii_softc *sc)
 	if (bmcr & E1000_CR_LOOPBACK)
 		mii->mii_media_active |= IFM_LOOP;
 
-	if ((((bmcr & E1000_CR_AUTO_NEG_ENABLE) != 0) &&
-	    ((bmsr & E1000_SR_AUTO_NEG_COMPLETE) == 0)) ||
-	    ((ssr & E1000_SSR_LINK) == 0) ||
-	    ((ssr & E1000_SSR_SPD_DPLX_RESOLVED) == 0)) {
+	if ((bmcr & E1000_CR_AUTO_NEG_ENABLE) != 0 &&
+	    (ssr & E1000_SSR_SPD_DPLX_RESOLVED) == 0) {
 		/* Erg, still trying, I guess... */
 		mii->mii_media_active |= IFM_NONE;
 		return;
 	}
 
 	if ((sc->mii_flags & MIIF_HAVEFIBER) == 0) {
-		if (ssr & E1000_SSR_1000MBS)
+		switch (ssr & E1000_SSR_SPEED) {
+		case E1000_SSR_1000MBS:
 			mii->mii_media_active |= IFM_1000_T;
-		else if (ssr & E1000_SSR_100MBS)
+			break;
+		case E1000_SSR_100MBS:
 			mii->mii_media_active |= IFM_100_TX;
-		else
+			break;
+		case E1000_SSR_10MBS:
 			mii->mii_media_active |= IFM_10_T;
+			break;
+		default:
+			mii->mii_media_active |= IFM_NONE;
+			return;
+		}
 	} else {
 		if (ssr & E1000_SSR_1000MBS)
 			mii->mii_media_active |= IFM_1000_SX;
@@ -497,6 +461,8 @@ e1000phy_status(struct mii_softc *sc)
 		mii->mii_media_active |= IFM_HDX;
 
 	if ((sc->mii_flags & MIIF_HAVEFIBER) == 0) {
+		ar = PHY_READ(sc, E1000_AR);
+		lpar = PHY_READ(sc, E1000_LPAR);
 		/* FLAG0==rx-flow-control FLAG1==tx-flow-control */
 		if ((ar & E1000_AR_PAUSE) && (lpar & E1000_LPAR_PAUSE)) {
 			mii->mii_media_active |= IFM_FLAG0 | IFM_FLAG1;
@@ -523,16 +489,19 @@ static int
 e1000phy_mii_phy_auto(struct e1000phy_softc *esc)
 {
 	struct mii_softc *sc;
+	uint16_t reg;
 
 	sc = &esc->mii_sc;
-	if ((sc->mii_flags & MIIF_HAVEFIBER) == 0)
-		PHY_WRITE(sc, E1000_AR, E1000_AR_10T | E1000_AR_10T_FD |
+	if ((sc->mii_flags & MIIF_HAVEFIBER) == 0) {
+		reg = PHY_READ(sc, E1000_AR);
+		reg |= E1000_AR_10T | E1000_AR_10T_FD |
 		    E1000_AR_100TX | E1000_AR_100TX_FD |
-		    E1000_AR_PAUSE | E1000_AR_ASM_DIR);
-	else
+		    E1000_AR_PAUSE | E1000_AR_ASM_DIR;
+		PHY_WRITE(sc, E1000_AR, reg | E1000_AR_SELECTOR_FIELD);
+	} else
 		PHY_WRITE(sc, E1000_AR, E1000_FA_1000X_FD | E1000_FA_1000X |
 		    E1000_FA_SYM_PAUSE | E1000_FA_ASYM_PAUSE);
-	if (esc->mii_model != MII_MODEL_MARVELL_E3082)
+	if ((sc->mii_extcapabilities & (EXTSR_1000TFDX | EXTSR_1000THDX)) != 0)
 		PHY_WRITE(sc, E1000_1GCR,
 		    E1000_1GCR_1000T_FD | E1000_1GCR_1000T);
 	PHY_WRITE(sc, E1000_CR,


More information about the svn-src-stable-7 mailing list