Subject: kern/9183: 100baseFX (fiber) support for SMC 9432FTX
To: None <gnats-bugs@gnats.netbsd.org>
From: None <salvet@ics.muni.cz>
List: netbsd-bugs
Date: 01/13/2000 10:42:54
>Number:         9183
>Category:       kern
>Synopsis:       100baseFX (fiber) support for SMC 9432FTX
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    kern-bug-people (Kernel Bug People)
>State:          open
>Class:          change-request
>Submitter-Id:   net
>Arrival-Date:   Thu Jan 13 10:42:00 2000
>Last-Modified:
>Originator:     Zdenek Salvet
>Organization:
Institute of Computer Science of Masaryk University, Brno, Czech Republic
>Release:        1.4.1, -current of Thu Jan 13 2000
>Environment:

>Description:
With change to lxtphy driver, SMC 9432FTX ethernet card with 100baseFX
interface could be supported. Resulting behaviour is not perfect unfortunately,
because there is no way to detect in PHY driver whether fiber interface
is physically available, so I had to hardwire 100baseFX-FDX as always
available. 

>How-To-Repeat:
>Fix:
Separate patches for 1.4.1 and -current follow:

========= PATCH FOR 1.4.1 ===================================
--- lxtphy.c.1.4.1	Thu Jan 13 17:20:31 2000
+++ lxtphy.c.new	Thu Jan 13 19:34:42 2000
@@ -143,10 +143,18 @@
 	    PHY_READ(sc, MII_BMSR) & ma->mii_capmask;
 	printf("%s: ", sc->mii_dev.dv_xname);
 	if ((sc->mii_capabilities & BMSR_MEDIAMASK) == 0)
-		printf("no media present");
+		/* printf("no media present") */ ;
 	else
 		mii_add_media(mii, sc->mii_capabilities,
 		    sc->mii_inst);
+
+	/* XXX
+	 * no way to detect the presence of a fiber interface
+         */
+	ADD(IFM_MAKEWORD(IFM_ETHER, IFM_100_FX, IFM_FDX, sc->mii_inst),
+	    BMCR_S100|BMCR_FDX);
+	printf(", 100baseFX-FDX");
+
 	printf("\n");
 #undef ADD
 }
@@ -200,13 +208,25 @@
 			 * XXX Not supported as a manual setting right now.
 			 */
 			return (EINVAL);
+		case IFM_100_FX:
+			/*
+			 * XXX
+			 * CONFIG_LEDC0 | CONFIG_LEDC1 part may be
+			 * specific to SMC9432FTX
+			 */
+			PHY_WRITE(sc, MII_LXTPHY_CONFIG,
+			   CONFIG_100BASEFX | CONFIG_LEDC0 | CONFIG_LEDC1);
+			PHY_WRITE(sc, MII_BMCR, BMCR_S100 | BMCR_FDX );
+			break;
 		default:
+			PHY_WRITE(sc, MII_LXTPHY_CONFIG, 0);
+
 			/*
 			 * BMCR data is stored in the ifmedia entry.
 			 */
-			PHY_WRITE(sc, MII_ANAR,
-			    mii_anar(ife->ifm_media));
+			PHY_WRITE(sc, MII_ANAR, mii_anar(ife->ifm_media));
 			PHY_WRITE(sc, MII_BMCR, ife->ifm_data);
+			break;
 		}
 		break;
 
@@ -269,7 +289,7 @@
 	struct mii_softc *sc;
 {
 	struct mii_data *mii = sc->mii_pdata;
-	int bmcr, csr;
+	int bmcr, csr, configreg;
 
 	mii->mii_media_status = IFM_AVALID;
 	mii->mii_media_active = IFM_ETHER;
@@ -292,6 +312,14 @@
 
 	if (bmcr & BMCR_LOOP)
 		mii->mii_media_active |= IFM_LOOP;
+
+	configreg = PHY_READ(sc, MII_LXTPHY_CONFIG);
+	if (configreg & CONFIG_100BASEFX) {
+		mii->mii_media_active |= IFM_100_FX;
+		if (csr & CSR_DUPLEX)
+			mii->mii_media_active |= IFM_FDX;
+		return;
+	}
 
 	if (bmcr & BMCR_AUTOEN) {
 		if ((csr & CSR_ACOMP) == 0) {
============== PATCH FOR -current of Thu Jan 13 2000 ====================
--- lxtphy.c.orig	Thu Jan 13 18:36:59 2000
+++ lxtphy.c	Thu Jan 13 19:01:46 2000
@@ -136,9 +136,20 @@
 	    PHY_READ(sc, MII_BMSR) & ma->mii_capmask;
 	printf("%s: ", sc->mii_dev.dv_xname);
 	if ((sc->mii_capabilities & BMSR_MEDIAMASK) == 0)
-		printf("no media present");
+		/* printf("no media present") */ ;
 	else
 		mii_add_media(sc);
+
+#define ADD(m, c)       ifmedia_add(&mii->mii_media, (m), (c), NULL)
+
+	/* XXX
+	 * no way to detect the presence of a fiber interface
+	 */
+	ADD(IFM_MAKEWORD(IFM_ETHER, IFM_100_FX, IFM_FDX, sc->mii_inst),
+		MII_MEDIA_100_TX_FDX);
+	printf(", 100baseFX-FDX");
+#undef ADD
+
 	printf("\n");
 }
 
@@ -186,8 +197,21 @@
 				return (0);
 			(void) mii_phy_auto(sc, 1);
 			break;
+		case IFM_100_FX:
+			/*
+			 * XXX
+			 * CONFIG_LEDC0 | CONFIG_LEDC1 part may be
+			 * specific to SMC9432FTX
+			 */
+			PHY_WRITE(sc, MII_LXTPHY_CONFIG,
+			    CONFIG_100BASEFX | CONFIG_LEDC0 | CONFIG_LEDC1);
+			PHY_WRITE(sc, MII_BMCR, BMCR_S100 | BMCR_FDX );
+			break;
+
 		default:
+			PHY_WRITE(sc, MII_LXTPHY_CONFIG, 0);
 			mii_phy_setmedia(sc);
+			break;
 		}
 		break;
 
@@ -255,7 +279,7 @@
 {
 	struct mii_data *mii = sc->mii_pdata;
 	struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
-	int bmcr, bmsr, csr;
+	int bmcr, bmsr, csr, configreg;
 
 	mii->mii_media_status = IFM_AVALID;
 	mii->mii_media_active = IFM_ETHER;
@@ -278,6 +302,14 @@
 
 	if (bmcr & BMCR_LOOP)
 		mii->mii_media_active |= IFM_LOOP;
+
+	configreg = PHY_READ(sc, MII_LXTPHY_CONFIG);
+	if (configreg & CONFIG_100BASEFX) {
+		 mii->mii_media_active |= IFM_100_FX;
+		 if (csr & CSR_DUPLEX)
+			 mii->mii_media_active |= IFM_FDX;
+		 return;
+	}
 
 	if (bmcr & BMCR_AUTOEN) {
 		bmsr = PHY_READ(sc, MII_BMSR) | PHY_READ(sc, MII_BMSR);
>Audit-Trail:
>Unformatted: