axe(4) (Belkin F5D5055) problems

Pyun YongHyeon pyunyh at gmail.com
Tue Apr 7 19:48:10 PDT 2009


On Tue, Apr 07, 2009 at 11:15:47PM +0300, Niki Denev wrote:

[...]

I've read the datasheet but I still don't understand why dsp
programming in truephy_reset is required. Anyway would you try
attached patch? And show me dmesg output generated by truephy(4).

> I have temporarily replaced the belkin USB ethernet interface with an
> Apple USB ethernet,
> which also uses the axe(4) driver, but is only 100Mbit/s.
> As I suspected the negotiation problems do not exist with it, and
> everything seemed ok, until
> it started to stop working exactly like the previous adapter.
> Pings start to return "buffer space not available" and replugging or
> "usbconfig reset" the interface
> returns it to normal status.
> 

This sounds like different issue to me. Let's focus on the
truephy(4) until axe(4) get a valid link report.

> It looks like that the packet loss that I've experienced with the
> Belkin gigabit adabter is one problem,
> and the interface stopping to work another.
> 
> P.S.: I don't know if it could be my USB hardware, because the machine
> is a little bit "exotic",
> an HP ex470 MediaSmartServer, which was supposedly designed to run
> only embedded version of
> Windows and has a nasty SiS chipset in it (with the unsupported sis191
> gigabit adapter)

There had been a post for SiS191 driver. Check mailing list
archives. Unfortunately I don't have SiS191 controller so I
couldn't write a driver and commit the posted driver to tree.
Even though the controller is not for high performance servers it
would be enough to most desktop users. At least SiS controllers
does not seem to require special workarounds for silicon bugs which
are commonly found on RealTek/Marvell controllers.

Alternatively you can use ndis(4) to use your SiS191 controller. I
don't know whether ndis(4) works for this controller though.
-------------- next part --------------
Index: sys/dev/mii/truephy.c
===================================================================
--- sys/dev/mii/truephy.c	(revision 190834)
+++ sys/dev/mii/truephy.c	(working copy)
@@ -66,6 +66,11 @@
 static void	truephy_reset(struct mii_softc *);
 static void	truephy_status(struct mii_softc *);
 
+struct truephy_softc {
+	struct mii_softc mii_sc;
+	int mii_model;
+};
+
 static device_method_t truephy_methods[] = {
 	/* device interface */
 	DEVMETHOD(device_probe,		truephy_probe),
@@ -76,6 +81,7 @@
 };
 
 static const struct mii_phydesc truephys[] = {
+	MII_PHY_DESC(AGERE,	ET1011C_1),
 	MII_PHY_DESC(AGERE,	ET1011C),
 	MII_PHY_END
 };
@@ -85,7 +91,7 @@
 static driver_t truephy_driver = {
 	"truephy",
 	truephy_methods,
-	sizeof(struct mii_softc)
+	sizeof(struct truephy_softc)
 };
 
 DRIVER_MODULE(truephy, miibus, truephy_driver, truephy_devclass, 0, 0);
@@ -139,15 +145,15 @@
 truephy_attach(device_t dev)
 {
 	struct mii_softc *sc;
+	struct truephy_softc *tsc;
 	struct mii_attach_args *ma;
 	struct mii_data *mii;
 
-	sc = device_get_softc(dev);
+	tsc = device_get_softc(dev);
+	sc = &tsc->mii_sc;
 	ma = device_get_ivars(dev);
 
 	sc->mii_phy = ma->mii_phyno;
-	if (sc->mii_anegticks == 0)
-		sc->mii_anegticks = MII_ANEGTICKS;
 	sc->mii_dev = device_get_parent(dev);
 	mii = device_get_softc(sc->mii_dev);
 	LIST_INSERT_HEAD(&mii->mii_phys, sc, mii_list);
@@ -161,13 +167,17 @@
 
 	mii->mii_instance++;
 
+	tsc->mii_model = MII_MODEL(ma->mii_id2);
+
 	truephy_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);
-		/* No 1000baseT half-duplex support */
-		sc->mii_extcapabilities &= ~EXTSR_1000THDX;
+		if (tsc->mii_model == MII_MODEL_AGERE_ET1011C) {
+			/* No 1000baseT half-duplex support */
+			sc->mii_extcapabilities &= ~EXTSR_1000THDX;
+		}
 	}
 
 	device_printf(dev, " ");
@@ -185,6 +195,7 @@
 static int
 truephy_service(struct mii_softc *sc, struct mii_data *mii, int cmd)
 {
+	struct truephy_softc *tsc = (struct truephy_softc *)sc;
 	struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
 	int bmcr;
 
@@ -214,22 +225,29 @@
 		if ((mii->mii_ifp->if_flags & IFF_UP) == 0)
 			break;
 
-		if (IFM_SUBTYPE(ife->ifm_media) != IFM_AUTO) {
-			bmcr = PHY_READ(sc, MII_BMCR) & ~BMCR_AUTOEN;
-			PHY_WRITE(sc, MII_BMCR, bmcr);
-			PHY_WRITE(sc, MII_BMCR, bmcr | BMCR_PDOWN);
-		}
+		switch (tsc->mii_model) {
+		case MII_MODEL_AGERE_ET1011C:
+			if (IFM_SUBTYPE(ife->ifm_media) != IFM_AUTO) {
+				bmcr = PHY_READ(sc, MII_BMCR) & ~BMCR_AUTOEN;
+				PHY_WRITE(sc, MII_BMCR, bmcr);
+				PHY_WRITE(sc, MII_BMCR, bmcr | BMCR_PDOWN);
+			}
 
-		mii_phy_setmedia(sc);
+			mii_phy_setmedia(sc);
 
-		if (IFM_SUBTYPE(ife->ifm_media) != IFM_AUTO) {
-			bmcr = PHY_READ(sc, MII_BMCR) & ~BMCR_PDOWN;
-			PHY_WRITE(sc, MII_BMCR, bmcr);
+			if (IFM_SUBTYPE(ife->ifm_media) != IFM_AUTO) {
+				bmcr = PHY_READ(sc, MII_BMCR) & ~BMCR_PDOWN;
+				PHY_WRITE(sc, MII_BMCR, bmcr);
 
-			if (IFM_SUBTYPE(ife->ifm_media) == IFM_1000_T) {
-				PHY_WRITE(sc, MII_BMCR,
-					  bmcr | BMCR_AUTOEN | BMCR_STARTNEG);
+				if (IFM_SUBTYPE(ife->ifm_media) == IFM_1000_T) {
+					PHY_WRITE(sc, MII_BMCR,
+					    bmcr | BMCR_AUTOEN | BMCR_STARTNEG);
+				}
 			}
+			break;
+		default:
+			mii_phy_setmedia(sc);
+			break;
 		}
 		break;
 
@@ -256,8 +274,14 @@
 static void
 truephy_reset(struct mii_softc *sc)
 {
+	struct truephy_softc *tsc;
 	int i;
 
+	tsc = (struct truephy_softc *)sc;
+	if (tsc->mii_model != MII_MODEL_AGERE_ET1011C) {
+		mii_phy_reset(sc);
+		return;
+	}
 	for (i = 0; i < 2; ++i) {
 		PHY_READ(sc, MII_PHYIDR1);
 		PHY_READ(sc, MII_PHYIDR2);
@@ -325,6 +349,15 @@
 	if (bmsr & BMSR_LINK)
 		mii->mii_media_status |= IFM_ACTIVE;
 
+	if (bmcr & BMCR_ISO) {
+		mii->mii_media_active |= IFM_NONE;
+		mii->mii_media_status = 0;
+		return;
+	}
+
+	if (bmcr & BMCR_LOOP)
+		mii->mii_media_active |= IFM_LOOP;
+
 	if (bmcr & BMCR_AUTOEN) {
 		if ((bmsr & BMSR_ACOMP) == 0) {
 			mii->mii_media_active |= IFM_NONE;
@@ -332,6 +365,12 @@
 		}
 	}
 
+	if (sr & TRUEPHY_SR_SBY) {
+		/* PHY is in standby mode. */
+		mii->mii_media_active |= IFM_NONE;
+		return;
+	}
+
 	switch (sr & TRUEPHY_SR_SPD_MASK) {
 	case TRUEPHY_SR_SPD_1000T:
 		mii->mii_media_active |= IFM_1000_T;
Index: sys/dev/mii/truephyreg.h
===================================================================
--- sys/dev/mii/truephyreg.h	(revision 190834)
+++ sys/dev/mii/truephyreg.h	(working copy)
@@ -55,6 +55,7 @@
 #define TRUEPHY_CONF_TXFIFO_32	0x3000
 
 #define TRUEPHY_SR		0x1a
+#define TRUEPHY_SR_SBY		0x8000
 #define TRUEPHY_SR_SPD_MASK	0x0300
 #define TRUEPHY_SR_SPD_1000T	0x0200
 #define TRUEPHY_SR_SPD_100TX	0x0100
Index: sys/dev/mii/miidevs
===================================================================
--- sys/dev/mii/miidevs	(revision 190834)
+++ sys/dev/mii/miidevs	(working copy)
@@ -109,6 +109,7 @@
  */
 
 /* Agere Systems PHYs */
+model AGERE ET1011C_1		0x0001 ET1011C 10/100/1000baseT PHY
 model AGERE ET1011C		0x0004 ET1011C 10/100/1000baseT PHY
 
 /* Altima Communications PHYs */


More information about the freebsd-current mailing list