Implement asynchronous autonegotiation when driven by the MII tick
(one-second clock). Prevents .5s delays every 5 seconds when the interface is up but there is no link. Fixes PR 7361.
This commit is contained in:
parent
9751244932
commit
83f9ab3c87
@ -1,7 +1,7 @@
|
||||
/* $NetBSD: exphy.c,v 1.15 1998/11/05 00:19:32 thorpej Exp $ */
|
||||
/* $NetBSD: exphy.c,v 1.16 1999/04/23 04:24:32 thorpej Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1998 The NetBSD Foundation, Inc.
|
||||
* Copyright (c) 1998, 1999 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
@ -201,7 +201,7 @@ exphy_service(sc, mii, cmd)
|
||||
*/
|
||||
if (PHY_READ(sc, MII_BMCR) & BMCR_AUTOEN)
|
||||
return (0);
|
||||
(void) mii_phy_auto(sc);
|
||||
(void) mii_phy_auto(sc, 1);
|
||||
break;
|
||||
case IFM_100_T4:
|
||||
/*
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* $NetBSD: icsphy.c,v 1.8 1998/11/05 04:08:01 thorpej Exp $ */
|
||||
/* $NetBSD: icsphy.c,v 1.9 1999/04/23 04:24:32 thorpej Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1998 The NetBSD Foundation, Inc.
|
||||
* Copyright (c) 1998, 1999 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
@ -193,7 +193,7 @@ icsphy_service(sc, mii, cmd)
|
||||
*/
|
||||
if (PHY_READ(sc, MII_BMCR) & BMCR_AUTOEN)
|
||||
return (0);
|
||||
(void) mii_phy_auto(sc);
|
||||
(void) mii_phy_auto(sc, 1);
|
||||
break;
|
||||
case IFM_100_T4:
|
||||
/*
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* $NetBSD: inphy.c,v 1.10 1998/11/05 04:08:02 thorpej Exp $ */
|
||||
/* $NetBSD: inphy.c,v 1.11 1999/04/23 04:24:32 thorpej Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1998 The NetBSD Foundation, Inc.
|
||||
* Copyright (c) 1998, 1999 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
@ -77,6 +77,7 @@
|
||||
#include <sys/device.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/errno.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <net/if_media.h>
|
||||
@ -201,7 +202,7 @@ inphy_service(sc, mii, cmd)
|
||||
*/
|
||||
if (PHY_READ(sc, MII_BMCR) & BMCR_AUTOEN)
|
||||
return (0);
|
||||
(void) mii_phy_auto(sc);
|
||||
(void) mii_phy_auto(sc, 1);
|
||||
break;
|
||||
case IFM_100_T4:
|
||||
/*
|
||||
@ -255,7 +256,8 @@ inphy_service(sc, mii, cmd)
|
||||
|
||||
sc->mii_ticks = 0;
|
||||
mii_phy_reset(sc);
|
||||
(void) mii_phy_auto(sc);
|
||||
if (mii_phy_auto(sc, 0) == EJUSTRETURN)
|
||||
return (0);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* $NetBSD: lxtphy.c,v 1.9 1998/11/05 04:08:02 thorpej Exp $ */
|
||||
/* $NetBSD: lxtphy.c,v 1.10 1999/04/23 04:24:32 thorpej Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1998 The NetBSD Foundation, Inc.
|
||||
* Copyright (c) 1998, 1999 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
@ -77,6 +77,7 @@
|
||||
#include <sys/device.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/errno.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <net/if_media.h>
|
||||
@ -192,7 +193,7 @@ lxtphy_service(sc, mii, cmd)
|
||||
*/
|
||||
if (PHY_READ(sc, MII_BMCR) & BMCR_AUTOEN)
|
||||
return (0);
|
||||
(void) mii_phy_auto(sc);
|
||||
(void) mii_phy_auto(sc, 1);
|
||||
break;
|
||||
case IFM_100_T4:
|
||||
/*
|
||||
@ -247,7 +248,8 @@ lxtphy_service(sc, mii, cmd)
|
||||
|
||||
sc->mii_ticks = 0;
|
||||
mii_phy_reset(sc);
|
||||
(void) mii_phy_auto(sc);
|
||||
if (mii_phy_auto(sc, 0) == EJUSTRETURN)
|
||||
return (0);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* $NetBSD: mii_physubr.c,v 1.2 1998/11/04 23:28:15 thorpej Exp $ */
|
||||
/* $NetBSD: mii_physubr.c,v 1.3 1999/04/23 04:24:32 thorpej Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1998 The NetBSD Foundation, Inc.
|
||||
* Copyright (c) 1998, 1999 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
@ -44,7 +44,9 @@
|
||||
#include <sys/param.h>
|
||||
#include <sys/device.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/errno.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <net/if_media.h>
|
||||
@ -52,28 +54,72 @@
|
||||
#include <dev/mii/mii.h>
|
||||
#include <dev/mii/miivar.h>
|
||||
|
||||
void mii_phy_auto_timeout __P((void *));
|
||||
|
||||
int
|
||||
mii_phy_auto(mii)
|
||||
mii_phy_auto(mii, waitfor)
|
||||
struct mii_softc *mii;
|
||||
{
|
||||
int bmsr, i;
|
||||
|
||||
PHY_WRITE(mii, MII_ANAR,
|
||||
BMSR_MEDIA_TO_ANAR(mii->mii_capabilities) | ANAR_CSMA);
|
||||
PHY_WRITE(mii, MII_BMCR, BMCR_AUTOEN | BMCR_STARTNEG);
|
||||
|
||||
/* Wait 500ms for it to complete. */
|
||||
for (i = 0; i < 500; i++) {
|
||||
if ((bmsr = PHY_READ(mii, MII_BMSR)) & BMSR_ACOMP)
|
||||
return (1);
|
||||
delay(1000);
|
||||
if ((mii->mii_flags & MIIF_DOINGAUTO) == 0) {
|
||||
PHY_WRITE(mii, MII_ANAR,
|
||||
BMSR_MEDIA_TO_ANAR(mii->mii_capabilities) | ANAR_CSMA);
|
||||
PHY_WRITE(mii, MII_BMCR, BMCR_AUTOEN | BMCR_STARTNEG);
|
||||
}
|
||||
|
||||
if (waitfor) {
|
||||
/* Wait 500ms for it to complete. */
|
||||
for (i = 0; i < 500; i++) {
|
||||
if ((bmsr = PHY_READ(mii, MII_BMSR)) & BMSR_ACOMP)
|
||||
return (0);
|
||||
delay(1000);
|
||||
#if 0
|
||||
if ((bmsr & BMSR_ACOMP) == 0)
|
||||
printf("%s: autonegotiation failed to complete\n",
|
||||
mii->mii_dev.dv_xname);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Don't need to worry about clearing MIIF_DOINGAUTO.
|
||||
* If that's set, a timeout is pending, and it will
|
||||
* clear the flag.
|
||||
*/
|
||||
return (EIO);
|
||||
}
|
||||
|
||||
/*
|
||||
* Just let it finish asynchronously. This is for the benefit of
|
||||
* the tick handler driving autonegotiation. Don't want 500ms
|
||||
* delays all the time while the system is running!
|
||||
*/
|
||||
if ((mii->mii_flags & MIIF_DOINGAUTO) == 0) {
|
||||
mii->mii_flags |= MIIF_DOINGAUTO;
|
||||
timeout(mii_phy_auto_timeout, mii, hz >> 1);
|
||||
}
|
||||
return (EJUSTRETURN);
|
||||
}
|
||||
|
||||
void
|
||||
mii_phy_auto_timeout(arg)
|
||||
void *arg;
|
||||
{
|
||||
struct mii_softc *mii = arg;
|
||||
int s, bmsr;
|
||||
|
||||
s = splnet();
|
||||
mii->mii_flags &= ~MIIF_DOINGAUTO;
|
||||
bmsr = PHY_READ(mii, MII_BMSR);
|
||||
#if 0
|
||||
if ((bmsr & BMSR_ACOMP) == 0)
|
||||
printf("%s: autonegotiation failed to complete\n",
|
||||
mii->mii_dev.dv_xname);
|
||||
sc->sc_dev.dv_xname);
|
||||
#endif
|
||||
return (0);
|
||||
|
||||
/* Update the media status. */
|
||||
(void) (*mii->mii_service)(mii, mii->mii_pdata, MII_POLLSTAT);
|
||||
splx(s);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* $NetBSD: miivar.h,v 1.7 1998/11/05 04:08:02 thorpej Exp $ */
|
||||
/* $NetBSD: miivar.h,v 1.8 1999/04/23 04:24:32 thorpej Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1998 The NetBSD Foundation, Inc.
|
||||
* Copyright (c) 1998, 1999 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
@ -128,6 +128,7 @@ typedef struct mii_softc mii_softc_t;
|
||||
|
||||
/* mii_flags */
|
||||
#define MIIF_NOISOLATE 0x0001 /* do not isolate the PHY */
|
||||
#define MIIF_DOINGAUTO 0x0002 /* doing autonegotiation */
|
||||
|
||||
/*
|
||||
* Used to attach a PHY to a parent.
|
||||
@ -161,7 +162,7 @@ void mii_add_media __P((struct mii_data *, int, int));
|
||||
|
||||
int mii_media_from_bmcr __P((int));
|
||||
|
||||
int mii_phy_auto __P((struct mii_softc *));
|
||||
int mii_phy_auto __P((struct mii_softc *, int));
|
||||
void mii_phy_reset __P((struct mii_softc *));
|
||||
|
||||
void ukphy_status __P((struct mii_softc *));
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* $NetBSD: nsphy.c,v 1.16 1998/11/05 04:08:02 thorpej Exp $ */
|
||||
/* $NetBSD: nsphy.c,v 1.17 1999/04/23 04:24:32 thorpej Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1998 The NetBSD Foundation, Inc.
|
||||
* Copyright (c) 1998, 1999 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
@ -77,6 +77,7 @@
|
||||
#include <sys/device.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/errno.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <net/if_media.h>
|
||||
@ -235,7 +236,7 @@ nsphy_service(sc, mii, cmd)
|
||||
*/
|
||||
if (PHY_READ(sc, MII_BMCR) & BMCR_AUTOEN)
|
||||
return (0);
|
||||
(void) mii_phy_auto(sc);
|
||||
(void) mii_phy_auto(sc, 1);
|
||||
break;
|
||||
case IFM_100_T4:
|
||||
/*
|
||||
@ -289,7 +290,8 @@ nsphy_service(sc, mii, cmd)
|
||||
|
||||
sc->mii_ticks = 0;
|
||||
mii_phy_reset(sc);
|
||||
(void) mii_phy_auto(sc);
|
||||
if (mii_phy_auto(sc, 0) == EJUSTRETURN)
|
||||
return (0);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* $NetBSD: qsphy.c,v 1.11 1998/11/05 04:08:02 thorpej Exp $ */
|
||||
/* $NetBSD: qsphy.c,v 1.12 1999/04/23 04:24:32 thorpej Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1998 The NetBSD Foundation, Inc.
|
||||
* Copyright (c) 1998, 1999 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
@ -193,7 +193,7 @@ qsphy_service(sc, mii, cmd)
|
||||
*/
|
||||
if (PHY_READ(sc, MII_BMCR) & BMCR_AUTOEN)
|
||||
return (0);
|
||||
(void) mii_phy_auto(sc);
|
||||
(void) mii_phy_auto(sc, 1);
|
||||
break;
|
||||
case IFM_100_T4:
|
||||
/*
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* $NetBSD: sqphy.c,v 1.8 1998/11/05 04:08:02 thorpej Exp $ */
|
||||
/* $NetBSD: sqphy.c,v 1.9 1999/04/23 04:24:32 thorpej Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1998 The NetBSD Foundation, Inc.
|
||||
* Copyright (c) 1998, 1999 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
@ -77,6 +77,7 @@
|
||||
#include <sys/device.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/errno.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <net/if_media.h>
|
||||
@ -192,7 +193,7 @@ sqphy_service(sc, mii, cmd)
|
||||
*/
|
||||
if (PHY_READ(sc, MII_BMCR) & BMCR_AUTOEN)
|
||||
return (0);
|
||||
(void) mii_phy_auto(sc);
|
||||
(void) mii_phy_auto(sc, 1);
|
||||
break;
|
||||
case IFM_100_T4:
|
||||
/*
|
||||
@ -246,7 +247,8 @@ sqphy_service(sc, mii, cmd)
|
||||
|
||||
sc->mii_ticks = 0;
|
||||
mii_phy_reset(sc);
|
||||
(void) mii_phy_auto(sc);
|
||||
if (mii_phy_auto(sc, 0) == EJUSTRETURN)
|
||||
return (0);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* $NetBSD: tlphy.c,v 1.16 1998/11/05 00:19:32 thorpej Exp $ */
|
||||
/* $NetBSD: tlphy.c,v 1.17 1999/04/23 04:24:32 thorpej Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1998 The NetBSD Foundation, Inc.
|
||||
* Copyright (c) 1998, 1999 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
@ -75,6 +75,7 @@
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/device.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/errno.h>
|
||||
|
||||
#include <machine/bus.h>
|
||||
|
||||
@ -98,6 +99,7 @@
|
||||
struct tlphy_softc {
|
||||
struct mii_softc sc_mii; /* generic PHY */
|
||||
int sc_tlphycap;
|
||||
int sc_need_acomp;
|
||||
};
|
||||
|
||||
int tlphymatch __P((struct device *, struct cfdata *, void *));
|
||||
@ -108,7 +110,8 @@ struct cfattach tlphy_ca = {
|
||||
};
|
||||
|
||||
int tlphy_service __P((struct mii_softc *, struct mii_data *, int));
|
||||
void tlphy_auto __P((struct tlphy_softc *));
|
||||
int tlphy_auto __P((struct tlphy_softc *, int));
|
||||
void tlphy_acomp __P((struct tlphy_softc *));
|
||||
void tlphy_status __P((struct tlphy_softc *));
|
||||
|
||||
int
|
||||
@ -206,6 +209,9 @@ tlphy_service(self, mii, cmd)
|
||||
struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
|
||||
int reg;
|
||||
|
||||
if ((sc->sc_mii.mii_flags & MIIF_DOINGAUTO) == 0 && sc->sc_need_acomp)
|
||||
tlphy_acomp(sc);
|
||||
|
||||
switch (cmd) {
|
||||
case MII_POLLSTAT:
|
||||
/*
|
||||
@ -239,7 +245,7 @@ tlphy_service(self, mii, cmd)
|
||||
* an autonegotiation cycle, so there's no such
|
||||
* thing as "already in auto mode".
|
||||
*/
|
||||
tlphy_auto(sc);
|
||||
(void) tlphy_auto(sc, 1);
|
||||
break;
|
||||
case IFM_10_2:
|
||||
case IFM_10_5:
|
||||
@ -295,7 +301,8 @@ tlphy_service(self, mii, cmd)
|
||||
|
||||
sc->sc_mii.mii_ticks = 0;
|
||||
mii_phy_reset(&sc->sc_mii);
|
||||
tlphy_auto(sc);
|
||||
if (tlphy_auto(sc, 0) == EJUSTRETURN)
|
||||
return (0);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -362,14 +369,41 @@ tlphy_status(sc)
|
||||
mii->mii_media_active |= IFM_10_T;
|
||||
}
|
||||
|
||||
int
|
||||
tlphy_auto(sc, waitfor)
|
||||
struct tlphy_softc *sc;
|
||||
int waitfor;
|
||||
{
|
||||
int error;
|
||||
|
||||
switch ((error = mii_phy_auto(&sc->sc_mii, waitfor))) {
|
||||
case EIO:
|
||||
/*
|
||||
* Just assume we're not in full-duplex mode.
|
||||
* XXX Check link and try AUI/BNC?
|
||||
*/
|
||||
PHY_WRITE(&sc->sc_mii, MII_BMCR, 0);
|
||||
break;
|
||||
|
||||
case EJUSTRETURN:
|
||||
/* Flag that we need to program when it completes. */
|
||||
sc->sc_need_acomp = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
tlphy_acomp(sc);
|
||||
}
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
void
|
||||
tlphy_auto(sc)
|
||||
tlphy_acomp(sc)
|
||||
struct tlphy_softc *sc;
|
||||
{
|
||||
int aner, anlpar;
|
||||
|
||||
if (mii_phy_auto(&sc->sc_mii) == 0)
|
||||
goto dflt;
|
||||
sc->sc_need_acomp = 0;
|
||||
|
||||
/*
|
||||
* Grr, braindead ThunderLAN PHY doesn't self-configure
|
||||
@ -386,11 +420,5 @@ tlphy_auto(sc)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
dflt:
|
||||
/*
|
||||
* Just assume we're not in full-duplex mode.
|
||||
* XXX Check link and try AUI/BNC?
|
||||
*/
|
||||
PHY_WRITE(&sc->sc_mii, MII_BMCR, 0);
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* $NetBSD: ukphy.c,v 1.1 1998/11/05 00:36:48 thorpej Exp $ */
|
||||
/* $NetBSD: ukphy.c,v 1.2 1999/04/23 04:24:32 thorpej Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1998 The NetBSD Foundation, Inc.
|
||||
* Copyright (c) 1998, 1999 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
@ -76,6 +76,7 @@
|
||||
#include <sys/device.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/errno.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <net/if_media.h>
|
||||
@ -189,7 +190,7 @@ ukphy_service(sc, mii, cmd)
|
||||
*/
|
||||
if (PHY_READ(sc, MII_BMCR) & BMCR_AUTOEN)
|
||||
return (0);
|
||||
(void) mii_phy_auto(sc);
|
||||
(void) mii_phy_auto(sc, 1);
|
||||
break;
|
||||
case IFM_100_T4:
|
||||
/*
|
||||
@ -243,7 +244,8 @@ ukphy_service(sc, mii, cmd)
|
||||
|
||||
sc->mii_ticks = 0;
|
||||
mii_phy_reset(sc);
|
||||
(void) mii_phy_auto(sc);
|
||||
if (mii_phy_auto(sc, 0) == EJUSTRETURN)
|
||||
return (0);
|
||||
break;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user