From owner-svn-src-all@FreeBSD.ORG Mon Oct 24 20:26:38 2011 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 655D2106566B; Mon, 24 Oct 2011 20:26:38 +0000 (UTC) (envelope-from yongari@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 4B95E8FC17; Mon, 24 Oct 2011 20:26:38 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id p9OKQcgx061210; Mon, 24 Oct 2011 20:26:38 GMT (envelope-from yongari@svn.freebsd.org) Received: (from yongari@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id p9OKQcmO061208; Mon, 24 Oct 2011 20:26:38 GMT (envelope-from yongari@svn.freebsd.org) Message-Id: <201110242026.p9OKQcmO061208@svn.freebsd.org> From: Pyun YongHyeon Date: Mon, 24 Oct 2011 20:26:38 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r226699 - head/sys/dev/dc X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 24 Oct 2011 20:26:38 -0000 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); } /*