Fixes PR kern/20700 reported by Darcy Cain

Make 1000baset connections work even when the user specifies media 1000baset
connections with ifconfig(8) rather then only when media auto is specified.

For a further discussion of this fix, see:
http://mail-index.NetBSD.org/current-users/2011/12/07/msg018561.html
This commit is contained in:
buhrow 2011-12-10 02:46:07 +00:00
parent 7559f8d444
commit a7162be315
1 changed files with 21 additions and 4 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: mii_physubr.c,v 1.72 2010/08/21 13:18:35 pgoyette Exp $ */
/* $NetBSD: mii_physubr.c,v 1.73 2011/12/10 02:46:07 buhrow Exp $ */
/*-
* Copyright (c) 1998, 1999, 2000, 2001 The NetBSD Foundation, Inc.
@ -35,7 +35,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: mii_physubr.c,v 1.72 2010/08/21 13:18:35 pgoyette Exp $");
__KERNEL_RCSID(0, "$NetBSD: mii_physubr.c,v 1.73 2011/12/10 02:46:07 buhrow Exp $");
#include <sys/param.h>
#include <sys/device.h>
@ -186,15 +186,21 @@ mii_phy_setmedia(struct mii_softc *sc)
bmcr |= BMCR_LOOP;
PHY_WRITE(sc, MII_ANAR, anar);
PHY_WRITE(sc, MII_BMCR, bmcr);
if (sc->mii_flags & MIIF_HAVE_GTCR)
PHY_WRITE(sc, MII_100T2CR, gtcr);
if (IFM_SUBTYPE(ife->ifm_media) == IFM_1000_T) {
mii_phy_auto(sc, 0);
} else {
PHY_WRITE(sc, MII_BMCR, bmcr);
}
}
int
mii_phy_auto(struct mii_softc *sc, int waitfor)
{
int i;
struct mii_data *mii = sc->mii_pdata;
struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
if ((sc->mii_flags & MIIF_DOINGAUTO) == 0) {
/*
@ -228,6 +234,16 @@ mii_phy_auto(struct mii_softc *sc, int waitfor)
(EXTSR_1000THDX|EXTSR_1000TFDX)))
anar |= ANAR_X_PAUSE_ASYM;
}
/*
*for 1000-base-T, autonegotiation mus be enabled, but
*if we're not set to auto, only advertise
*1000-base-T with the link partner.
*/
if (IFM_SUBTYPE(ife->ifm_media) == IFM_1000_T) {
anar &= ~(ANAR_T4|ANAR_TX_FD|ANAR_TX|ANAR_10_FD|ANAR_10);
}
PHY_WRITE(sc, MII_ANAR, anar);
if (sc->mii_flags & MIIF_HAVE_GTCR) {
uint16_t gtcr = 0;
@ -310,7 +326,8 @@ mii_phy_tick(struct mii_softc *sc)
* status so we can generate an announcement if the status
* changes.
*/
if (IFM_SUBTYPE(ife->ifm_media) != IFM_AUTO)
if ((IFM_SUBTYPE(ife->ifm_media) != IFM_AUTO) &&
(IFM_SUBTYPE(ife->ifm_media) != IFM_1000_T))
return (0);
/* Read the status register twice; BMSR_LINK is latch-low. */