From f0a2eb28e5b6e57d79c33f6a823f27131e81f2aa Mon Sep 17 00:00:00 2001 From: msaitoh Date: Fri, 23 Feb 2007 03:03:10 +0000 Subject: [PATCH] fix some negotiation problems on wm(4). will fix PR#30078, PR#30490, PR#30906, PR#33429, PR#35386. --- sys/dev/mii/igphy.c | 14 ++++++++++++-- sys/dev/mii/makphy.c | 19 ++++++++++++++++--- sys/dev/pci/if_wm.c | 24 ++++++++++++++++++------ 3 files changed, 46 insertions(+), 11 deletions(-) diff --git a/sys/dev/mii/igphy.c b/sys/dev/mii/igphy.c index dfdcebaeac94..c6260d2ecb6d 100644 --- a/sys/dev/mii/igphy.c +++ b/sys/dev/mii/igphy.c @@ -1,4 +1,4 @@ -/* $NetBSD: igphy.c,v 1.10 2006/11/16 21:24:07 christos Exp $ */ +/* $NetBSD: igphy.c,v 1.11 2007/02/23 03:03:10 msaitoh Exp $ */ /* * The Intel copyright applies to the analog register setup, and the @@ -77,7 +77,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: igphy.c,v 1.10 2006/11/16 21:24:07 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: igphy.c,v 1.11 2007/02/23 03:03:10 msaitoh Exp $"); #include "opt_mii.h" @@ -272,6 +272,16 @@ igphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd) if ((mii->mii_ifp->if_flags & IFF_UP) == 0) break; + reg = PHY_READ(sc, MII_IGPHY_PORT_CTRL); + if (IFM_SUBTYPE(ife->ifm_media) == IFM_AUTO) { + reg |= PSCR_AUTO_MDIX; + reg &= ~PSCR_FORCE_MDI_MDIX; + PHY_WRITE(sc, MII_IGPHY_PORT_CTRL, reg); + } else { + reg &= ~(PSCR_AUTO_MDIX | PSCR_FORCE_MDI_MDIX); + PHY_WRITE(sc, MII_IGPHY_PORT_CTRL, reg); + } + mii_phy_setmedia(sc); break; diff --git a/sys/dev/mii/makphy.c b/sys/dev/mii/makphy.c index 5147f42188cf..e9d2be069a60 100644 --- a/sys/dev/mii/makphy.c +++ b/sys/dev/mii/makphy.c @@ -1,4 +1,4 @@ -/* $NetBSD: makphy.c,v 1.22 2006/11/16 21:24:07 christos Exp $ */ +/* $NetBSD: makphy.c,v 1.23 2007/02/23 03:03:10 msaitoh Exp $ */ /*- * Copyright (c) 1998, 1999, 2000, 2001 The NetBSD Foundation, Inc. @@ -71,7 +71,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: makphy.c,v 1.22 2006/11/16 21:24:07 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: makphy.c,v 1.23 2007/02/23 03:03:10 msaitoh Exp $"); #include #include @@ -97,9 +97,10 @@ CFATTACH_DECL(makphy, sizeof(struct mii_softc), static int makphy_service(struct mii_softc *, struct mii_data *, int); static void makphy_status(struct mii_softc *); +static void makphy_reset(struct mii_softc *); static const struct mii_phy_funcs makphy_funcs = { - makphy_service, makphy_status, mii_phy_reset, + makphy_service, makphy_status, makphy_reset, }; static const struct mii_phydesc makphys[] = { @@ -166,6 +167,18 @@ makphyattach(struct device *parent, struct device *self, void *aux) aprint_normal("\n"); } +static void +makphy_reset(struct mii_softc *sc) +{ + uint16_t pscr; + + /* Assert CRS on transmit */ + pscr = PHY_READ(sc, MII_MAKPHY_PSCR); + PHY_WRITE(sc, MII_MAKPHY_PSCR, pscr | PSCR_CRS_ON_TX); + + mii_phy_reset(sc); +} + static int makphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd) { diff --git a/sys/dev/pci/if_wm.c b/sys/dev/pci/if_wm.c index de7fa5b64c2f..0131ab24fb9f 100644 --- a/sys/dev/pci/if_wm.c +++ b/sys/dev/pci/if_wm.c @@ -1,4 +1,4 @@ -/* $NetBSD: if_wm.c,v 1.132 2007/02/21 23:48:12 thorpej Exp $ */ +/* $NetBSD: if_wm.c,v 1.133 2007/02/23 03:03:10 msaitoh Exp $ */ /* * Copyright (c) 2001, 2002, 2003, 2004 Wasabi Systems, Inc. @@ -47,7 +47,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.132 2007/02/21 23:48:12 thorpej Exp $"); +__KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.133 2007/02/23 03:03:10 msaitoh Exp $"); #include "bpfilter.h" #include "rnd.h" @@ -3992,6 +3992,15 @@ wm_gmii_reset(struct wm_softc *sc) CSR_WRITE(sc, WMREG_CTRL, sc->sc_ctrl); delay(20000); } else { + /* + * With 82543, we need to force speed and duplex on the MAC + * equal to what the PHY speed and duplex configuration is. + * In addition, we need to perform a hardware reset on the PHY + * to take it out of reset. + */ + sc->sc_ctrl |= CTRL_FRCSPD | CTRL_FRCFDX; + CSR_WRITE(sc, WMREG_CTRL, sc->sc_ctrl); + /* The PHY reset pin is active-low. */ reg = CSR_READ(sc, WMREG_CTRL_EXT); reg &= ~((CTRL_EXT_SWDPIO_MASK << CTRL_EXT_SWDPIO_SHIFT) | @@ -4002,7 +4011,7 @@ wm_gmii_reset(struct wm_softc *sc) delay(10); CSR_WRITE(sc, WMREG_CTRL_EXT, reg); - delay(10); + delay(10000); CSR_WRITE(sc, WMREG_CTRL_EXT, reg | CTRL_EXT_SWDPIN(4)); delay(10); @@ -4038,7 +4047,7 @@ wm_gmii_mediainit(struct wm_softc *sc) * XXXbouyer - I'm not sure this is right for the 80003, * the em driver only sets CTRL_SLU here - but it seems to work. */ - sc->sc_ctrl |= CTRL_SLU | CTRL_ASDE; + sc->sc_ctrl |= CTRL_SLU; CSR_WRITE(sc, WMREG_CTRL, sc->sc_ctrl); /* Initialize our media structures and probe the GMII. */ @@ -4100,8 +4109,9 @@ wm_gmii_mediachange(struct ifnet *ifp) if (ifp->if_flags & IFF_UP) { sc->sc_ctrl &= ~(CTRL_SPEED_MASK | CTRL_FD); sc->sc_ctrl |= CTRL_SLU; - if (IFM_SUBTYPE(ife->ifm_media) == IFM_AUTO) { - sc->sc_ctrl |= CTRL_ASDE; + if ((IFM_SUBTYPE(ife->ifm_media) == IFM_AUTO) + || (sc->sc_type > WM_T_82543)) { + sc->sc_ctrl &= ~(CTRL_FRCSPD | CTRL_FRCFDX); } else { sc->sc_ctrl &= ~CTRL_ASDE; sc->sc_ctrl |= CTRL_FRCSPD | CTRL_FRCFDX; @@ -4123,6 +4133,8 @@ wm_gmii_mediachange(struct ifnet *ifp) } } CSR_WRITE(sc, WMREG_CTRL, sc->sc_ctrl); + if (sc->sc_type <= WM_T_82543) + wm_gmii_reset(sc); mii_mediachg(&sc->sc_mii); } return (0);