Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 24 Oct 2011 20:26:38 +0000 (UTC)
From:      Pyun YongHyeon <yongari@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r226699 - head/sys/dev/dc
Message-ID:  <201110242026.p9OKQcmO061208@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: yongari
Date: Mon Oct 24 20:26:37 2011
New Revision: 226699
URL: http://svn.freebsd.org/changeset/base/226699

Log:
  When driver is run for the first time there would be no established
  link such that calling dc_setcfg() right after media change would
  be meaningless unless controller in question is not Davicom DM9102.
  Ideally dc_setcfg() should be called when speed/duplex is resolved
  otherwise it would reprogram controller with wrong speed/duplex
  information.  Because MII status change callback already calls
  dc_setcfg() I think calling dc_setcfg() in dc_init_locked() is
  wrong.  For instance, it would take some time to establish a link
  after mii_mediachg(), so blindly calling dc_setcfg() right after
  mii_mediachg() will always yield wrong media configuration.
  
  Extend dc_ifmedia_upd() to handle media change and still allow
  21143 and Davidcom controllers program speed/duplex regardless of
  current resolved speed/duplex of link. In theory 21143 may not need
  to call dc_setcfg() right after media change, but leave it as it is
  because there are too many variants to test that change.  Probably
  dc(4) shall need a PHY reset in dc_ifmedia_upd() but it's hard to
  verify correctness of the change.
  
  This change reliably makes ULi M5263 establish a link.
  
  While I'm here correctly report media change result. Previously it
  always reported a success.

Modified:
  head/sys/dev/dc/if_dc.c

Modified: head/sys/dev/dc/if_dc.c
==============================================================================
--- head/sys/dev/dc/if_dc.c	Mon Oct 24 18:35:16 2011	(r226698)
+++ head/sys/dev/dc/if_dc.c	Mon Oct 24 20:26:37 2011	(r226699)
@@ -252,6 +252,7 @@ static void dc_stop(struct dc_softc *);
 static void dc_watchdog(void *);
 static int dc_shutdown(device_t);
 static int dc_ifmedia_upd(struct ifnet *);
+static int dc_ifmedia_upd_locked(struct dc_softc *);
 static void dc_ifmedia_sts(struct ifnet *, struct ifmediareq *);
 
 static int dc_dma_alloc(struct dc_softc *);
@@ -3740,8 +3741,7 @@ dc_init_locked(struct dc_softc *sc)
 	ifp->if_drv_flags |= IFF_DRV_RUNNING;
 	ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
 
-	mii_mediachg(mii);
-	dc_setcfg(sc, sc->dc_if_media);
+	dc_ifmedia_upd_locked(sc);
 
 	/* Clear missed frames and overflow counter. */
 	CSR_READ_4(sc, DC_FRAMESDISCARDED);
@@ -3767,25 +3767,37 @@ static int
 dc_ifmedia_upd(struct ifnet *ifp)
 {
 	struct dc_softc *sc;
-	struct mii_data *mii;
-	struct ifmedia *ifm;
+	int error;
 
 	sc = ifp->if_softc;
-	mii = device_get_softc(sc->dc_miibus);
 	DC_LOCK(sc);
-	mii_mediachg(mii);
-	ifm = &mii->mii_media;
-
-	if (DC_IS_INTEL(sc))
-		dc_setcfg(sc, ifm->ifm_media);
-	else if (DC_IS_DAVICOM(sc) &&
-	    IFM_SUBTYPE(ifm->ifm_media) == IFM_HPNA_1)
-		dc_setcfg(sc, ifm->ifm_media);
-	else
-		sc->dc_link = 0;
+	error = dc_ifmedia_upd_locked(sc);
 	DC_UNLOCK(sc);
+	return (error);
+}
 
-	return (0);
+static int
+dc_ifmedia_upd_locked(struct dc_softc *sc)
+{
+	struct mii_data *mii;
+	struct ifmedia *ifm;
+	int error;
+
+	DC_LOCK_ASSERT(sc);
+
+	sc->dc_link = 0;
+	mii = device_get_softc(sc->dc_miibus);
+	error = mii_mediachg(mii);
+	if (error == 0) {
+		ifm = &mii->mii_media;
+		if (DC_IS_INTEL(sc))
+			dc_setcfg(sc, ifm->ifm_media);
+		else if (DC_IS_DAVICOM(sc) &&
+		    IFM_SUBTYPE(ifm->ifm_media) == IFM_HPNA_1)
+			dc_setcfg(sc, ifm->ifm_media);
+	}
+
+	return (error);
 }
 
 /*



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201110242026.p9OKQcmO061208>