Date: Thu, 2 Apr 2009 16:58:45 +0000 (UTC) From: Warner Losh <imp@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r190643 - head/sys/dev/ed Message-ID: <200904021658.n32GwjQc070351@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
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
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200904021658.n32GwjQc070351>