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.
This commit is contained in:
Pyun YongHyeon 2011-10-24 20:26:37 +00:00
parent 30ce7fee44
commit d7e9ac7523
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=226699

View File

@ -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);
}
/*