svn commit: r218788 - head/sys/dev/dc
Pyun YongHyeon
yongari at FreeBSD.org
Fri Feb 18 02:58:10 UTC 2011
Author: yongari
Date: Fri Feb 18 02:58:09 2011
New Revision: 218788
URL: http://svn.freebsd.org/changeset/base/218788
Log:
Apply special PHY initialization code for 21143 controllers before
any other media configuration. Otherwise some 21143 controller
cannot establish a link. While I'm here remove the PHY
initialization code in dc_setcfg(). Since dc_setcfg() is called
whenever link state is changed, having the PHY initialization code
in dc_setcfg() resulted in continuous link flips.
After driver resets SIA, use default SIA transmit/receive
configuration instead of disabling autosense/autonegotiation.
Otherwise, controller fails to establish a link as well as losing
auto-negotiation capability. For manual media configuration, always
configure 21143 controller with specified media to ensure media
change. This change makes ANA-6922 establish link with/without
auto-negotiation.
While I'm here be more strict on link UP/DOWN detection logic.
Many thanks to marius who fixed several bugs in initial patch and
even tested the patch on a couple of dc(4) controllers.
PR: kern/79262
Reviewed by: marius
Tested by: marius
Modified:
head/sys/dev/dc/if_dc.c
Modified: head/sys/dev/dc/if_dc.c
==============================================================================
--- head/sys/dev/dc/if_dc.c Fri Feb 18 02:14:53 2011 (r218787)
+++ head/sys/dev/dc/if_dc.c Fri Feb 18 02:58:09 2011 (r218788)
@@ -944,23 +944,45 @@ static void
dc_miibus_statchg(device_t dev)
{
struct dc_softc *sc;
+ struct ifnet *ifp;
struct mii_data *mii;
struct ifmedia *ifm;
sc = device_get_softc(dev);
- if (DC_IS_ADMTEK(sc))
- return;
mii = device_get_softc(sc->dc_miibus);
+ ifp = sc->dc_ifp;
+ if (mii == NULL || ifp == NULL ||
+ (ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
+ return;
+
ifm = &mii->mii_media;
if (DC_IS_DAVICOM(sc) &&
IFM_SUBTYPE(ifm->ifm_media) == IFM_HPNA_1) {
dc_setcfg(sc, ifm->ifm_media);
sc->dc_if_media = ifm->ifm_media;
- } else {
- dc_setcfg(sc, mii->mii_media_active);
- sc->dc_if_media = mii->mii_media_active;
+ return;
+ }
+
+ sc->dc_link = 0;
+ if ((mii->mii_media_status & (IFM_ACTIVE | IFM_AVALID)) ==
+ (IFM_ACTIVE | IFM_AVALID)) {
+ switch (IFM_SUBTYPE(mii->mii_media_active)) {
+ case IFM_10_T:
+ case IFM_100_TX:
+ sc->dc_link = 1;
+ break;
+ default:
+ break;
+ }
}
+ if (sc->dc_link == 0)
+ return;
+
+ sc->dc_if_media = mii->mii_media_active;
+ if (DC_IS_ADMTEK(sc))
+ return;
+ dc_setcfg(sc, mii->mii_media_active);
}
/*
@@ -1404,8 +1426,6 @@ dc_setcfg(struct dc_softc *sc, int media
if (!DC_IS_DAVICOM(sc))
DC_SETBIT(sc, DC_NETCFG, DC_NETCFG_PORTSEL);
DC_CLRBIT(sc, DC_10BTCTRL, 0xFFFF);
- if (DC_IS_INTEL(sc))
- dc_apply_fixup(sc, IFM_AUTO);
} else {
if (DC_IS_PNIC(sc)) {
DC_PN_GPIO_SETBIT(sc, DC_PN_GPIO_SPEEDSEL);
@@ -1415,10 +1435,6 @@ dc_setcfg(struct dc_softc *sc, int media
DC_SETBIT(sc, DC_NETCFG, DC_NETCFG_PORTSEL);
DC_SETBIT(sc, DC_NETCFG, DC_NETCFG_PCS);
DC_SETBIT(sc, DC_NETCFG, DC_NETCFG_SCRAMBLER);
- if (DC_IS_INTEL(sc))
- dc_apply_fixup(sc,
- (media & IFM_GMASK) == IFM_FDX ?
- IFM_100_TX | IFM_FDX : IFM_100_TX);
}
}
@@ -1442,8 +1458,6 @@ dc_setcfg(struct dc_softc *sc, int media
if (!DC_IS_DAVICOM(sc))
DC_SETBIT(sc, DC_NETCFG, DC_NETCFG_PORTSEL);
DC_CLRBIT(sc, DC_10BTCTRL, 0xFFFF);
- if (DC_IS_INTEL(sc))
- dc_apply_fixup(sc, IFM_AUTO);
} else {
if (DC_IS_PNIC(sc)) {
DC_PN_GPIO_CLRBIT(sc, DC_PN_GPIO_SPEEDSEL);
@@ -1463,9 +1477,6 @@ dc_setcfg(struct dc_softc *sc, int media
DC_SETBIT(sc, DC_SIARESET, DC_SIA_RESET);
DC_CLRBIT(sc, DC_10BTCTRL,
DC_TCTL_AUTONEGENBL);
- dc_apply_fixup(sc,
- (media & IFM_GMASK) == IFM_FDX ?
- IFM_10_T | IFM_FDX : IFM_10_T);
DELAY(20000);
}
}
@@ -1537,7 +1548,7 @@ dc_reset(struct dc_softc *sc)
*/
if (DC_IS_INTEL(sc)) {
DC_SETBIT(sc, DC_SIARESET, DC_SIA_RESET);
- CSR_WRITE_4(sc, DC_10BTCTRL, 0);
+ CSR_WRITE_4(sc, DC_10BTCTRL, 0xFFFFFFFF);
CSR_WRITE_4(sc, DC_WATCHDOG, 0);
}
}
@@ -2963,11 +2974,8 @@ dc_tick(void *xsc)
*/
if ((DC_HAS_BROKEN_RXSTATE(sc) || (CSR_READ_4(sc,
DC_ISR) & DC_ISR_RX_STATE) == DC_RXSTATE_WAIT) &&
- sc->dc_cdata.dc_tx_cnt == 0) {
+ sc->dc_cdata.dc_tx_cnt == 0)
mii_tick(mii);
- if (!(mii->mii_media_status & IFM_ACTIVE))
- sc->dc_link = 0;
- }
}
} else
mii_tick(mii);
@@ -2991,12 +2999,8 @@ dc_tick(void *xsc)
* that time, packets will stay in the send queue, and once the
* link comes up, they will be flushed out to the wire.
*/
- if (!sc->dc_link && mii->mii_media_status & IFM_ACTIVE &&
- IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE) {
- sc->dc_link++;
- if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
- dc_start_locked(ifp);
- }
+ if (sc->dc_link != 0 && !IFQ_DRV_IS_EMPTY(&ifp->if_snd))
+ dc_start_locked(ifp);
if (sc->dc_flags & DC_21143_NWAY && !sc->dc_link)
callout_reset(&sc->dc_stat_ch, hz/10, dc_tick, sc);
@@ -3421,6 +3425,7 @@ dc_init_locked(struct dc_softc *sc)
{
struct ifnet *ifp = sc->dc_ifp;
struct mii_data *mii;
+ struct ifmedia *ifm;
DC_LOCK_ASSERT(sc);
@@ -3431,6 +3436,10 @@ dc_init_locked(struct dc_softc *sc)
*/
dc_stop(sc);
dc_reset(sc);
+ if (DC_IS_INTEL(sc)) {
+ ifm = &mii->mii_media;
+ dc_apply_fixup(sc, ifm->ifm_media);
+ }
/*
* Set cache alignment and burst length.
@@ -3574,12 +3583,12 @@ dc_init_locked(struct dc_softc *sc)
DC_SETBIT(sc, DC_NETCFG, DC_NETCFG_RX_ON);
CSR_WRITE_4(sc, DC_RXSTART, 0xFFFFFFFF);
- mii_mediachg(mii);
- dc_setcfg(sc, sc->dc_if_media);
-
ifp->if_drv_flags |= IFF_DRV_RUNNING;
ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
+ mii_mediachg(mii);
+ dc_setcfg(sc, sc->dc_if_media);
+
/* Don't start the ticker if this is a homePNA link. */
if (IFM_SUBTYPE(mii->mii_media.ifm_media) == IFM_HPNA_1)
sc->dc_link = 1;
@@ -3610,7 +3619,9 @@ dc_ifmedia_upd(struct ifnet *ifp)
mii_mediachg(mii);
ifm = &mii->mii_media;
- if (DC_IS_DAVICOM(sc) &&
+ 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
More information about the svn-src-all
mailing list