Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/sbus * remove full duplex modes for the internal tra...
details: https://anonhg.NetBSD.org/src/rev/a982093b93bd
branches: trunk
changeset: 479860:a982093b93bd
user: pk <pk%NetBSD.org@localhost>
date: Thu Dec 23 16:39:56 1999 +0000
description:
* remove full duplex modes for the internal transceiver
* internal transceiver needs to be reset for the BMSR_LINK bit to
be even remotely reliable
* because of previous, maintain link state, so we won't be sensing speed
all the time when interface flags need to be changed (e.g. entering/exiting
promiscuous mode)
* in auto-speed mode, report link condition changes on the console
diffstat:
sys/dev/sbus/be.c | 86 +++++++++++++++++++++++++++++++++++++++++-------------
1 files changed, 65 insertions(+), 21 deletions(-)
diffs (213 lines):
diff -r 6a50c6e3e52b -r a982093b93bd sys/dev/sbus/be.c
--- a/sys/dev/sbus/be.c Thu Dec 23 16:07:58 1999 +0000
+++ b/sys/dev/sbus/be.c Thu Dec 23 16:39:56 1999 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: be.c,v 1.12 1999/12/22 16:05:12 pk Exp $ */
+/* $NetBSD: be.c,v 1.13 1999/12/23 16:39:56 pk Exp $ */
/*-
* Copyright (c) 1999 The NetBSD Foundation, Inc.
@@ -140,6 +140,9 @@
int sc_mii_inst; /* instance of internal phy */
int sc_mii_active; /* currently active medium */
int sc_mii_ticks; /* tick counter */
+ int sc_mii_flags; /* phy status flags */
+#define MIIF_HAVELINK 0x04000000
+ int sc_intphy_curspeed; /* Established link speed */
struct qec_softc *sc_qec; /* QEC parent */
@@ -413,18 +416,15 @@
IFM_MAKEWORD(IFM_ETHER,IFM_10_T,0,instance),
0, NULL);
ifmedia_add(&sc->sc_media,
- IFM_MAKEWORD(IFM_ETHER,IFM_10_T,IFM_FDX,instance),
- BMCR_FDX, NULL);
- ifmedia_add(&sc->sc_media,
IFM_MAKEWORD(IFM_ETHER,IFM_100_TX,0,instance),
BMCR_S100, NULL);
ifmedia_add(&sc->sc_media,
- IFM_MAKEWORD(IFM_ETHER,IFM_100_TX,IFM_FDX,instance),
- BMCR_S100|BMCR_FDX, NULL);
- ifmedia_add(&sc->sc_media,
IFM_MAKEWORD(IFM_ETHER,IFM_AUTO,0,instance),
0, NULL);
+ printf("on-board transceiver at %s: 10baseT, 100baseTX, auto\n",
+ self->dv_xname);
+
be_mii_reset(sc, BE_PHY_INTERNAL);
/* Only set default medium here if there's no external PHY */
if (instance == 0) {
@@ -688,7 +688,8 @@
s = splnet();
bestop(sc);
- beinit(sc);
+ if ((sc->sc_ethercom.ec_if.if_flags & IFF_UP) != 0)
+ beinit(sc);
splx(s);
}
@@ -1070,10 +1071,7 @@
qec_meminit(&sc->sc_rb, BE_PKT_BUF_SZ);
- be_mii_sync(sc);
-
bestop(sc);
- be_ifmedia_upd(ifp);
ea = sc->sc_enaddr;
bus_space_write_4(t, br, BE_BRI_MACADDR0, (ea[0] << 8) | ea[1]);
@@ -1140,6 +1138,7 @@
ifp->if_flags |= IFF_RUNNING;
ifp->if_flags &= ~IFF_OACTIVE;
+ be_ifmedia_upd(ifp);
timeout(be_tick, sc, hz);
splx(s);
}
@@ -1262,7 +1261,6 @@
bus_space_handle_t tr = sc->sc_tr;
u_int32_t v;
-printf(" gating phy %d\n", phy);
be_mii_sync(sc);
v = ~(TCVR_PAL_EXTLBACK | TCVR_PAL_MSENSE | TCVR_PAL_LTENABLE);
@@ -1407,7 +1405,6 @@
for (n = 16; n >= 0; n--) {
int bmcr = be_mii_readreg((struct device *)sc, phy, MII_BMCR);
-printf("be_mii_reset: bmcr = 0x%x\n", bmcr);
if ((bmcr & BMCR_RESET) == 0)
break;
DELAY(20);
@@ -1416,6 +1413,7 @@
printf("%s: bmcr reset failed\n", sc->sc_dev.dv_xname);
return (EIO);
}
+
return (0);
}
@@ -1506,6 +1504,7 @@
{
struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
int bmcr, bmsr;
+ int error;
switch (cmd) {
case MII_POLLSTAT:
@@ -1519,32 +1518,49 @@
case MII_MEDIACHG:
- bmcr = be_mii_readreg((void *)sc, BE_PHY_INTERNAL, MII_BMCR);
-
/*
* If the media indicates a different PHY instance,
* isolate ourselves.
*/
if (IFM_INST(ife->ifm_media) != sc->sc_mii_inst) {
-printf(" MII_MEDIACHG: isolating; bmcr = 0x%x\n", bmcr);
+ bmcr = be_mii_readreg((void *)sc,
+ BE_PHY_INTERNAL, MII_BMCR);
be_mii_writereg((void *)sc,
BE_PHY_INTERNAL, MII_BMCR, bmcr | BMCR_ISO);
+ sc->sc_mii_flags &= ~MIIF_HAVELINK;
+ sc->sc_intphy_curspeed = 0;
return (0);
}
+ if ((error = be_mii_reset(sc, BE_PHY_INTERNAL)) != 0)
+ return (error);
+
+ bmcr = be_mii_readreg((void *)sc, BE_PHY_INTERNAL, MII_BMCR);
+
+ /*
+ * Select the new mode and take out of isolation
+ */
if (IFM_SUBTYPE(ife->ifm_media) == IFM_100_TX)
bmcr |= BMCR_S100;
else if (IFM_SUBTYPE(ife->ifm_media) == IFM_10_T)
bmcr &= ~BMCR_S100;
+ else if (IFM_SUBTYPE(ife->ifm_media) == IFM_AUTO) {
+ if ((sc->sc_mii_flags & MIIF_HAVELINK) != 0) {
+ bmcr &= ~BMCR_S100;
+ bmcr |= sc->sc_intphy_curspeed;
+ } else {
+ /* Keep isolated until link is up */
+ bmcr |= BMCR_ISO;
+ sc->sc_mii_flags |= MIIF_DOINGAUTO;
+ }
+ }
if ((IFM_OPTIONS(ife->ifm_media) & IFM_FDX) != 0)
bmcr |= BMCR_FDX;
else
bmcr &= ~BMCR_FDX;
- /* Select the new mode and take out of isolation */
- bmcr &= ~BMCR_ISO;
be_mii_writereg((void *)sc, BE_PHY_INTERNAL, MII_BMCR, bmcr);
break;
@@ -1575,24 +1591,52 @@
if ((bmsr & BMSR_LINK) != 0) {
/* We have a carrier */
+ bmcr = be_mii_readreg((void *)sc,
+ BE_PHY_INTERNAL, MII_BMCR);
+
+ if ((sc->sc_mii_flags & MIIF_DOINGAUTO) != 0) {
+ bmcr = be_mii_readreg((void *)sc,
+ BE_PHY_INTERNAL, MII_BMCR);
+
+ sc->sc_mii_flags |= MIIF_HAVELINK;
+ sc->sc_intphy_curspeed = (bmcr & BMCR_S100);
+ sc->sc_mii_flags &= ~MIIF_DOINGAUTO;
+
+ bmcr &= ~BMCR_ISO;
+ be_mii_writereg((void *)sc,
+ BE_PHY_INTERNAL, MII_BMCR, bmcr);
+
+ printf("%s: link up at %s Mbps\n",
+ sc->sc_dev.dv_xname,
+ (bmcr & BMCR_S100) ? "100" : "10");
+ }
return (0);
}
+ if ((sc->sc_mii_flags & MIIF_DOINGAUTO) == 0) {
+ sc->sc_mii_flags |= MIIF_DOINGAUTO;
+ sc->sc_mii_flags &= ~MIIF_HAVELINK;
+ sc->sc_intphy_curspeed = 0;
+ printf("%s: link down\n", sc->sc_dev.dv_xname);
+ }
+
/* Only retry autonegotiation every 5 seconds. */
- if (++sc->sc_mii_ticks != 5)
+ if (++sc->sc_mii_ticks < 5)
return(0);
sc->sc_mii_ticks = 0;
bmcr = be_mii_readreg((void *)sc, BE_PHY_INTERNAL, MII_BMCR);
/* Just flip the fast speed bit */
-printf(" MII_TICK: flipping: 0x%x -> ", bmcr);
bmcr ^= BMCR_S100;
-printf("0x%x\n", bmcr);
be_mii_writereg((void *)sc, BE_PHY_INTERNAL, MII_BMCR, bmcr);
break;
case MII_DOWN:
+ /* Isolate this phy */
+ bmcr = be_mii_readreg((void *)sc, BE_PHY_INTERNAL, MII_BMCR);
+ be_mii_writereg((void *)sc,
+ BE_PHY_INTERNAL, MII_BMCR, bmcr | BMCR_ISO);
return (0);
}
Home |
Main Index |
Thread Index |
Old Index