From owner-svn-src-head@FreeBSD.ORG Thu Apr 2 16:58:45 2009 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id CFE751065672; Thu, 2 Apr 2009 16:58:45 +0000 (UTC) (envelope-from imp@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id BE3A28FC0A; Thu, 2 Apr 2009 16:58:45 +0000 (UTC) (envelope-from imp@FreeBSD.org) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id n32GwjXF070352; Thu, 2 Apr 2009 16:58:45 GMT (envelope-from imp@svn.freebsd.org) Received: (from imp@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id n32GwjQc070351; Thu, 2 Apr 2009 16:58:45 GMT (envelope-from imp@svn.freebsd.org) Message-Id: <200904021658.n32GwjQc070351@svn.freebsd.org> From: Warner Losh Date: Thu, 2 Apr 2009 16:58:45 +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: r190643 - head/sys/dev/ed X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 02 Apr 2009 16:58:46 -0000 Author: imp Date: Thu Apr 2 16:58:45 2009 New Revision: 190643 URL: http://svn.freebsd.org/changeset/base/190643 Log: Force an autonegotiation at attach time for all the attached PHYs for ed cards. There's a number of minor nits in a lot of the PHYs on the PC Cards that use the Axis AX88190 or DLink DL10019 and DL10022 chips. Forcing the autonegotiation doesn't seem to cause problems on the cards that have sane PHYs, but makes several cards I have work without further workarounds. I'm not 100% sure that kicking the PHY and resetting them is the right thing to do on the media change callback. Other NICs seem to need this and do similar things. Modified: head/sys/dev/ed/if_ed_pccard.c Modified: head/sys/dev/ed/if_ed_pccard.c ============================================================================== --- head/sys/dev/ed/if_ed_pccard.c Thu Apr 2 16:51:41 2009 (r190642) +++ head/sys/dev/ed/if_ed_pccard.c Thu Apr 2 16:58:45 2009 (r190643) @@ -382,6 +382,26 @@ ed_pccard_add_modem(device_t dev) } static int +ed_pccard_kick_phy(struct ed_softc *sc) +{ + struct mii_softc *miisc; + struct mii_data *mii; + + /* + * Many of the PHYs that wind up on PC Cards are weird in + * this way. Generally, we don't need to worry so much about + * the Isolation protocol since there's only one PHY in + * these designs, so this workaround is reasonable. + */ + mii = device_get_softc(sc->miibus); + LIST_FOREACH(miisc, &mii->mii_phys, mii_list) { + miisc->mii_flags |= MIIF_FORCEANEG; + mii_phy_reset(miisc); + } + return (mii_mediachg(mii)); +} + +static int ed_pccard_media_ioctl(struct ed_softc *sc, struct ifreq *ifr, u_long command) { struct mii_data *mii; @@ -584,6 +604,7 @@ ed_pccard_attach(device_t dev) sc->sc_tick = ed_pccard_tick; sc->sc_mediachg = ed_pccard_mediachg; sc->sc_media_ioctl = ed_pccard_media_ioctl; + ed_pccard_kick_phy(sc); } if (sc->modem_rid != -1) ed_pccard_add_modem(dev); @@ -963,6 +984,7 @@ ed_pccard_ax88x90_mii_readbits(struct ed val++; ed_asic_outb(sc, ED_AX88X90_MIIBUS, mdio | ED_AX88X90_MII_CLK); } + printf("AX88x90 %#x+%#x Reading %d bits: %x\n", (unsigned int)sc->port_bsh, sc->asic_offset, nbits, val); return val; } @@ -1062,6 +1084,7 @@ ed_pccard_tc5299j_mii_readbits(struct ed u_int val = 0; uint8_t cr; + printf("Reading %d bits\n", nbits); cr = ed_nic_inb(sc, ED_P0_CR); ed_nic_outb(sc, ED_P0_CR, cr | ED_CR_PAGE_3); @@ -1124,6 +1147,7 @@ ed_miibus_readreg(device_t dev, int phy, failed = (*sc->mii_readbits)(sc, ED_MII_ACK_BITS); val = (*sc->mii_readbits)(sc, ED_MII_DATA_BITS); (*sc->mii_writebits)(sc, ED_MII_IDLE, ED_MII_IDLE_BITS); + printf("Reading phy %d reg %#x returning %#x (valid %d)\n", phy, reg, val, !failed); return (failed ? 0 : val); } @@ -1132,6 +1156,7 @@ ed_miibus_writereg(device_t dev, int phy { struct ed_softc *sc; + printf("Writing phy %d reg %#x data %#x\n", phy, reg, data); sc = device_get_softc(dev); /* See ed_miibus_readreg for details */ if (sc->chip_type == ED_CHIP_TYPE_AX88790) { @@ -1158,14 +1183,15 @@ static int ed_ifmedia_upd(struct ifnet *ifp) { struct ed_softc *sc; - struct mii_data *mii; + int error; sc = ifp->if_softc; if (sc->miibus == NULL) return (ENXIO); - - mii = device_get_softc(sc->miibus); - return mii_mediachg(mii); + ED_LOCK(sc); + error = ed_pccard_kick_phy(sc); + ED_UNLOCK(sc); + return (error); } static void