summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrad Smith <brad@cvs.openbsd.org>2005-05-27 09:24:02 +0000
committerBrad Smith <brad@cvs.openbsd.org>2005-05-27 09:24:02 +0000
commit7292c74355e5d99197ee5abe163eb46765d7cc9c (patch)
treecfecca8c89850b424a33b10d577dbed989b97914
parent141f6c9496a550f50379a449e7eca41c9b368813 (diff)
modernize and cleanup the nsgphy code, using mii_phy_setmedia/mii_phy_tick
and the generic MII #defines
-rw-r--r--sys/dev/mii/nsgphy.c230
-rw-r--r--sys/dev/mii/nsgphyreg.h120
2 files changed, 51 insertions, 299 deletions
diff --git a/sys/dev/mii/nsgphy.c b/sys/dev/mii/nsgphy.c
index aedf5968594..4516ea10278 100644
--- a/sys/dev/mii/nsgphy.c
+++ b/sys/dev/mii/nsgphy.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: nsgphy.c,v 1.15 2005/03/26 04:40:09 krw Exp $ */
+/* $OpenBSD: nsgphy.c,v 1.16 2005/05/27 09:24:01 brad Exp $ */
/*
* Copyright (c) 2001 Wind River Systems
* Copyright (c) 2001
@@ -77,8 +77,6 @@ struct cfdriver nsgphy_cd = {
int nsgphy_service(struct mii_softc *, struct mii_data *, int);
void nsgphy_status(struct mii_softc *);
-int nsgphy_mii_phy_auto(struct mii_softc *, int);
-
const struct mii_phy_funcs nsgphy_funcs = {
nsgphy_service, nsgphy_status, mii_phy_reset,
};
@@ -120,9 +118,7 @@ nsgphyattach(struct device *parent, struct device *self, void *aux)
sc->mii_funcs = &nsgphy_funcs;
sc->mii_pdata = mii;
sc->mii_flags = ma->mii_flags;
- sc->mii_anegticks = MII_ANEGTICKS_GIGE;
-
- PHY_RESET(sc);
+ sc->mii_anegticks = MII_ANEGTICKS;
sc->mii_capabilities =
PHY_READ(sc, MII_BMSR) & ma->mii_capmask;
@@ -131,15 +127,6 @@ nsgphyattach(struct device *parent, struct device *self, void *aux)
if ((sc->mii_capabilities & BMSR_MEDIAMASK) ||
(sc->mii_extcapabilities & EXTSR_MEDIAMASK))
mii_phy_add_media(sc);
-
-#if 0
- strap = PHY_READ(sc, MII_GPHYTER_STRAP);
- printf("%s: strapped to %s mode", sc->mii_dev.dv_xname,
- (strap & STRAP_MS_VAL) ? "master" : "slave");
- if (strap & STRAP_NC_MODE)
- printf(", pre-C5 BCM5400 compat enabled");
- printf("\n");
-#endif
}
int
@@ -177,53 +164,7 @@ nsgphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd)
if ((mii->mii_ifp->if_flags & IFF_UP) == 0)
break;
- switch (IFM_SUBTYPE(ife->ifm_media)) {
- case IFM_AUTO:
- (void) nsgphy_mii_phy_auto(sc, 0);
- break;
- case IFM_1000_T:
- if ((ife->ifm_media & IFM_GMASK) == IFM_FDX) {
- PHY_WRITE(sc, NSGPHY_MII_BMCR,
- NSGPHY_BMCR_FDX|NSGPHY_BMCR_SPD1);
- } else {
- PHY_WRITE(sc, NSGPHY_MII_BMCR,
- NSGPHY_BMCR_SPD1);
- }
- PHY_WRITE(sc, NSGPHY_MII_ANAR, NSGPHY_SEL_TYPE);
-
- /*
- * When setting the link manually, one side must
- * be the master and the other the slave. However
- * ifmedia doesn't give us a good way to specify
- * this, so we fake it by using one of the LINK
- * flags. If LINK0 is set, we program the PHY to
- * be a master, otherwise it's a slave.
- */
- if ((mii->mii_ifp->if_flags & IFF_LINK0)) {
- PHY_WRITE(sc, NSGPHY_MII_1000CTL,
- NSGPHY_1000CTL_MSE|NSGPHY_1000CTL_MSC);
- } else {
- PHY_WRITE(sc, NSGPHY_MII_1000CTL,
- NSGPHY_1000CTL_MSE);
- }
- break;
- case IFM_100_T4:
- /*
- * XXX Not supported as a manual setting right now.
- */
- return (EINVAL);
- case IFM_NONE:
- PHY_WRITE(sc, MII_BMCR, BMCR_ISO|BMCR_PDOWN);
- break;
- default:
- /*
- * BMCR data is stored in the ifmedia entry.
- */
- PHY_WRITE(sc, MII_ANAR,
- mii_anar(ife->ifm_media));
- PHY_WRITE(sc, MII_BMCR, ife->ifm_data);
- break;
- }
+ mii_phy_setmedia(sc);
break;
case MII_TICK:
@@ -233,36 +174,8 @@ nsgphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd)
if (IFM_INST(ife->ifm_media) != sc->mii_inst)
return (0);
- /*
- * Only used for autonegotiation.
- */
- if (IFM_SUBTYPE(ife->ifm_media) != IFM_AUTO)
+ if (mii_phy_tick(sc) == EJUSTRETURN)
return (0);
-
- /*
- * Is the interface even up?
- */
- if ((mii->mii_ifp->if_flags & IFF_UP) == 0)
- return (0);
-
- /*
- * Only retry autonegotiation every mii_anegticks seconds.
- */
- if (++sc->mii_ticks <= sc->mii_anegticks)
- return (0);
-
- sc->mii_ticks = 0;
-
- /*
- * Check to see if we have link.
- */
- reg = PHY_READ(sc, NSGPHY_MII_PHYSUP);
- if (reg & NSGPHY_PHYSUP_LNKSTS)
- break;
-
- PHY_RESET(sc);
- if (nsgphy_mii_phy_auto(sc, 0) == EJUSTRETURN)
- return(0);
break;
case MII_DOWN:
mii_phy_down(sc);
@@ -281,123 +194,58 @@ void
nsgphy_status(struct mii_softc *sc)
{
struct mii_data *mii = sc->mii_pdata;
- int bmsr, bmcr, physup, anlpar, gstat;
+ struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
+ int bmsr, bmcr, physup, gtsr;
mii->mii_media_status = IFM_AVALID;
mii->mii_media_active = IFM_ETHER;
- bmsr = PHY_READ(sc, NSGPHY_MII_BMSR) | PHY_READ(sc, NSGPHY_MII_BMSR);
+ bmsr = PHY_READ(sc, MII_BMSR) | PHY_READ(sc, MII_BMSR);
+
physup = PHY_READ(sc, NSGPHY_MII_PHYSUP);
- if (physup & NSGPHY_PHYSUP_LNKSTS)
+
+ if (physup & PHY_SUP_LINK)
mii->mii_media_status |= IFM_ACTIVE;
- bmcr = PHY_READ(sc, NSGPHY_MII_BMCR);
+ bmcr = PHY_READ(sc, MII_BMCR);
+ if (bmcr & BMCR_ISO) {
+ mii->mii_media_active |= IFM_NONE;
+ mii->mii_media_status = 0;
+ return;
+ }
- if (bmcr & NSGPHY_BMCR_LOOP)
+ if (bmcr & BMCR_LOOP)
mii->mii_media_active |= IFM_LOOP;
- if (bmcr & NSGPHY_BMCR_AUTOEN) {
- if ((bmsr & NSGPHY_BMSR_ACOMP) == 0) {
+ if (bmcr & BMCR_AUTOEN) {
+ if ((bmsr & BMSR_ACOMP) == 0) {
/* Erg, still trying, I guess... */
mii->mii_media_active |= IFM_NONE;
return;
}
- anlpar = PHY_READ(sc, NSGPHY_MII_ANLPAR);
- gstat = PHY_READ(sc, NSGPHY_MII_1000STS);
- if (gstat & NSGPHY_1000STS_LPFD)
- mii->mii_media_active |= IFM_1000_T|IFM_FDX;
- else if (gstat & NSGPHY_1000STS_LPHD)
- mii->mii_media_active |= IFM_1000_T|IFM_HDX;
- else if (anlpar & NSGPHY_ANLPAR_100T4)
- mii->mii_media_active |= IFM_100_T4;
- else if (anlpar & NSGPHY_ANLPAR_100FDX)
- mii->mii_media_active |= IFM_100_TX|IFM_FDX;
- else if (anlpar & NSGPHY_ANLPAR_100HDX)
- mii->mii_media_active |= IFM_100_TX;
- else if (anlpar & NSGPHY_ANLPAR_10FDX)
- mii->mii_media_active |= IFM_10_T|IFM_FDX;
- else if (anlpar & NSGPHY_ANLPAR_10HDX)
- mii->mii_media_active |= IFM_10_T|IFM_HDX;
- else
- mii->mii_media_active |= IFM_NONE;
- return;
- }
- switch(bmcr & (NSGPHY_BMCR_SPD1|NSGPHY_BMCR_SPD0)) {
- case NSGPHY_S1000:
- mii->mii_media_active |= IFM_1000_T;
- break;
- case NSGPHY_S100:
- mii->mii_media_active |= IFM_100_TX;
- break;
- case NSGPHY_S10:
- mii->mii_media_active |= IFM_10_T;
- break;
- default:
- break;
- }
-
- if (bmcr & NSGPHY_BMCR_FDX)
- mii->mii_media_active |= IFM_FDX;
- else
- mii->mii_media_active |= IFM_HDX;
-
- return;
-}
+ switch (physup & (PHY_SUP_SPEED1|PHY_SUP_SPEED0)) {
+ case PHY_SUP_SPEED1:
+ mii->mii_media_active |= IFM_1000_T;
+ gtsr = PHY_READ(sc, MII_100T2SR);
+ if (gtsr & GTSR_MS_RES)
+ mii->mii_media_active |= IFM_ETH_MASTER;
+ break;
+ case PHY_SUP_SPEED0:
+ mii->mii_media_active |= IFM_100_TX;
+ break;
-int
-nsgphy_mii_phy_auto(struct mii_softc *sc, int waitfor)
-{
- int bmsr, ktcr = 0, i;
-
- if ((sc->mii_flags & MIIF_DOINGAUTO) == 0) {
- PHY_RESET(sc);
- PHY_WRITE(sc, NSGPHY_MII_BMCR, 0);
- DELAY(1000);
- ktcr = PHY_READ(sc, NSGPHY_MII_1000CTL);
- PHY_WRITE(sc, NSGPHY_MII_1000CTL, ktcr |
- (NSGPHY_1000CTL_AFD|NSGPHY_1000CTL_AHD));
- ktcr = PHY_READ(sc, NSGPHY_MII_1000CTL);
- DELAY(1000);
- PHY_WRITE(sc, NSGPHY_MII_ANAR,
- BMSR_MEDIA_TO_ANAR(sc->mii_capabilities) | ANAR_CSMA);
- DELAY(1000);
- PHY_WRITE(sc, NSGPHY_MII_BMCR,
- NSGPHY_BMCR_AUTOEN | NSGPHY_BMCR_STARTNEG);
- }
+ case 0:
+ mii->mii_media_active |= IFM_10_T;
+ break;
- if (waitfor) {
- /* Wait 500ms for it to complete. */
- for (i = 0; i < 500; i++) {
- if ((bmsr = PHY_READ(sc, NSGPHY_MII_BMSR)) &
- NSGPHY_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
+ default:
+ mii->mii_media_active |= IFM_NONE;
+ mii->mii_media_status = 0;
}
-
- /*
- * 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 ((sc->mii_flags & MIIF_DOINGAUTO) == 0) {
- sc->mii_flags |= MIIF_DOINGAUTO;
- timeout_set(&sc->mii_phy_timo, mii_phy_auto_timeout, sc);
- timeout_add(&sc->mii_phy_timo, hz >> 1);
- }
- return (EJUSTRETURN);
+ if (physup & PHY_SUP_DUPLEX)
+ mii->mii_media_active |= IFM_FDX;
+ } else
+ mii->mii_media_active = ife->ifm_media;
}
diff --git a/sys/dev/mii/nsgphyreg.h b/sys/dev/mii/nsgphyreg.h
index 4ab42281422..145b6475840 100644
--- a/sys/dev/mii/nsgphyreg.h
+++ b/sys/dev/mii/nsgphyreg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: nsgphyreg.h,v 1.4 2003/10/22 09:39:29 jmc Exp $ */
+/* $OpenBSD: nsgphyreg.h,v 1.5 2005/05/27 09:24:01 brad Exp $ */
/*
* Copyright (c) 2001 Wind River Systems
* Copyright (c) 2001
@@ -31,7 +31,7 @@
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
- * $FreeBSD$
+ * $FreeBSD: /usr/local/www/cvsroot/FreeBSD/src/sys/dev/mii/nsgphyreg.h,v 1.3 2002/04/29 11:57:28 phk Exp $
*/
#ifndef _DEV_MII_NSGPHYREG_H_
@@ -41,110 +41,6 @@
* NatSemi DP83891 registers
*/
-#define NSGPHY_MII_BMCR 0x00
-#define NSGPHY_BMCR_RESET 0x8000
-#define NSGPHY_BMCR_LOOP 0x4000
-#define NSGPHY_BMCR_SPD0 0x2000 /* speed select, lower bit */
-#define NSGPHY_BMCR_AUTOEN 0x1000 /* Autoneg enabled */
-#define NSGPHY_BMCR_PDOWN 0x0800 /* Power down */
-#define NSGPHY_BMCR_ISO 0x0400 /* Isolate */
-#define NSGPHY_BMCR_STARTNEG 0x0200 /* Restart autoneg */
-#define NSGPHY_BMCR_FDX 0x0100 /* Duplex mode */
-#define NSGPHY_BMCR_CTEST 0x0080 /* Collision test enable */
-#define NSGPHY_BMCR_SPD1 0x0040 /* Speed select, upper bit */
-
-#define NSGPHY_S1000 NSGPHY_BMCR_SPD1 /* 1000mbps */
-#define NSGPHY_S100 NSGPHY_BMCR_SPD0 /* 100mpbs */
-#define NSGPHY_S10 0 /* 10mbps */
-
-#define NSGPHY_MII_BMSR 0x01
-#define NSGPHY_BMSR_100BT4 0x8000 /* 100baseT4 support */
-#define NSGPHY_BMSR_100FDX 0x4000 /* 100baseTX full duplex */
-#define NSGPHY_BMSR_100HDX 0x2000 /* 100baseTX half duplex */
-#define NSGPHY_BMSR_10FDX 0x1000 /* 10baseT full duplex */
-#define NSGPHY_BMSR_10HDX 0x0800 /* 10baseT half duplex */
-#define NSGPHY_BMSR_100T2FDX 0x0400 /* 100baseT2 full duplex */
-#define NSGPHY_BMSR_100T2HDX 0x0200 /* 100baseT2 full duplex */
-#define NSGPHY_BMSR_EXTSTS 0x0100 /* 1000baseT Extended status present */
-#define NSGPHY_BMSR_PRESUB 0x0040 /* Preamble suppression */
-#define NSGPHY_BMSR_ACOMP 0x0020 /* Autoneg complete */
-#define NSGPHY_BMSR_RFAULT 0x0010 /* Remote fault condition occurred */
-#define NSGPHY_BMSR_ANEG 0x0008 /* Autoneg capable */
-#define NSGPHY_BMSR_LINK 0x0004 /* Link status */
-#define NSGPHY_BMSR_JABBER 0x0002 /* Jabber detected */
-#define NSGPHY_BMSR_EXT 0x0001 /* Extended capability */
-
-#define NSGPHY_MII_ANAR 0x04
-#define NSGPHY_ANAR_NP 0x8000 /* Next page */
-#define NSGPHY_ANAR_RF 0x2000 /* Remote fault */
-#define NSGPHY_ANAR_ASP 0x0800 /* Asymmetric Pause */
-#define NSGPHY_ANAR_PC 0x0400 /* Pause capable */
-#define NSGPHY_ANAR_100T4 0x0200 /* 100baseT4 support */
-#define NSGPHY_ANAR_100FDX 0x0100 /* 100baseTX full duplex support */
-#define NSGPHY_ANAR_100HDX 0x0080 /* 100baseTX half duplex support */
-#define NSGPHY_ANAR_10FDX 0x0040 /* 10baseT full duplex support */
-#define NSGPHY_ANAR_10HDX 0x0020 /* 10baseT half duplex support */
-#define NSGPHY_ANAR_SEL 0x001F /* selector field, 00001=Ethernet */
-
-#define NSGPHY_MII_ANLPAR 0x05
-#define NSGPHY_ANLPAR_NP 0x8000 /* Next page */
-#define NSGPHY_ANLPAR_RF 0x2000 /* Remote fault */
-#define NSGPHY_ANLPAR_ASP 0x0800 /* Asymmetric Pause */
-#define NSGPHY_ANLPAR_PC 0x0400 /* Pause capable */
-#define NSGPHY_ANLPAR_100T4 0x0200 /* 100baseT4 support */
-#define NSGPHY_ANLPAR_100FDX 0x0100 /* 100baseTX full duplex support */
-#define NSGPHY_ANLPAR_100HDX 0x0080 /* 100baseTX half duplex support */
-#define NSGPHY_ANLPAR_10FDX 0x0040 /* 10baseT full duplex support */
-#define NSGPHY_ANLPAR_10HDX 0x0020 /* 10baseT half duplex support */
-#define NSGPHY_ANLPAR_SEL 0x001F /* selector field, 00001=Ethernet */
-
-#define NSGPHY_SEL_TYPE 0x0001 /* ethernet */
-
-#define NSGPHY_MII_ANER 0x06
-#define NSGPHY_ANER_PDF 0x0010 /* Parallel detection fault */
-#define NSGPHY_ANER_LPNP 0x0008 /* Link partner can next page */
-#define NSGPHY_ANER_NP 0x0004 /* Local PHY can next page */
-#define NSGPHY_ANER_RX 0x0002 /* Next page received */
-#define NSGPHY_ANER_LPAN 0x0001 /* Link partner autoneg capable */
-
-#define NSGPHY_MII_NEXTP 0x07 /* Next page */
-#define NSGPHY_NEXTP_NP 0x8000 /* Next page indication */
-#define NSGPHY_NEXTP_MP 0x2000 /* Message page */
-#define NSGPHY_NEXTP_ACK2 0x1000 /* Acknowledge 2 */
-#define NSGPHY_NEXTP_TOGGLE 0x0800 /* Toggle */
-#define NSGPHY_NEXTP_CODE 0x07FF /* Code field */
-
-#define NSGPHY_MII_NEXTP_LP 0x08 /* Next page of link partner */
-#define NSGPHY_NEXTPLP_NP 0x8000 /* Next page indication */
-#define NSGPHY_NEXTPLP_MP 0x2000 /* Message page */
-#define NSGPHY_NEXTPLP_ACK2 0x1000 /* Acknowledge 2 */
-#define NSGPHY_NEXTPLP_TOGGLE 0x0800 /* Toggle */
-#define NSGPHY_NEXTPLP_CODE 0x07FF /* Code field */
-
-#define NSGPHY_MII_1000CTL 0x09 /* 1000baseT control */
-#define NSGPHY_1000CTL_TST 0xE000 /* test modes */
-#define NSGPHY_1000CTL_MSE 0x1000 /* Master/Slave config enable */
-#define NSGPHY_1000CTL_MSC 0x0800 /* Master/Slave setting */
-#define NSGPHY_1000CTL_RD 0x0400 /* Port type: Repeater/DTE */
-#define NSGPHY_1000CTL_AFD 0x0200 /* Advertise full duplex */
-#define NSGPHY_1000CTL_AHD 0x0100 /* Advertise half duplex */
-
-#define NSGPHY_MII_1000STS 0x0A /* 1000baseT status */
-#define NSGPHY_1000STS_MSF 0x8000 /* Master/slave fault */
-#define NSGPHY_1000STS_MSR 0x4000 /* Master/slave result */
-#define NSGPHY_1000STS_LRS 0x2000 /* Local receiver status */
-#define NSGPHY_1000STS_RRS 0x1000 /* Remote receiver status */
-#define NSGPHY_1000STS_LPFD 0x0800 /* Link partner can FD */
-#define NSGPHY_1000STS_LPHD 0x0400 /* Link partner can HD */
-#define NSGPHY_1000STS_ASM_DIR 0x0200 /* Asymmetric pause capable */
-#define NSGPHY_1000STS_IEC 0x00FF /* Idle error count */
-
-#define NSGPHY_MII_EXTSTS 0x0F /* Extended status */
-#define NSGPHY_EXTSTS_X_FD_CAP 0x8000 /* 1000base-X FD capable */
-#define NSGPHY_EXTSTS_X_HD_CAP 0x4000 /* 1000base-X HD capable */
-#define NSGPHY_EXTSTS_T_FD_CAP 0x2000 /* 1000base-T FD capable */
-#define NSGPHY_EXTSTS_T_HD_CAP 0x1000 /* 1000base-T HD capable */
-
#define NSGPHY_MII_STRAPOPT 0x10 /* Strap options */
#define NSGPHY_STRAPOPT_PHYADDR 0xF800 /* PHY address */
#define NSGPHY_STRAPOPT_COMPAT 0x0400 /* Broadcom compat mode */
@@ -154,11 +50,19 @@
#define NSGPHY_STRAPOPT_1000HDX 0x0010 /* Advertise 1000 half-duplex */
#define NSGPHY_STRAPOPT_1000FDX 0x0008 /* Advertise 1000 full-duplex */
#define NSGPHY_STRAPOPT_100_ADV 0x0004 /* Advertise 100 full/half-duplex */
-#define NSGPHY_STRAPOPT_SPDSEL 0x0003 /* speed selection */
+#define NSGPHY_STRAPOPT_SPEED1 0x0002 /* speed selection */
+#define NSGPHY_STRAPOPT_SPEED0 0x0001 /* speed selection */
+#define NSGPHY_STRAPOPT_SPDSEL (NSGPHY_STRAPOPT_SPEED1|NSGPHY_STRAPOPT_SPEED0)
#define NSGPHY_MII_PHYSUP 0x11 /* PHY support/current status */
-#define NSGPHY_PHYSUP_SPDSTS 0x0018 /* speed status */
+#define PHY_SUP_SPEED1 0x0010 /* speed bit 1 */
+#define PHY_SUP_SPEED0 0x0008 /* speed bit 1 */
+#define NSGPHY_PHYSUP_SPEED1 0x0010 /* speed status */
+#define NSGPHY_PHYSUP_SPEED0 0x0008 /* speed status */
+#define NSGPHY_PHYSUP_SPDSTS (NSGPHY_PHYSUP_SPEED1|NSGPHY_PHYSUP_SPEED0)
#define NSGPHY_PHYSUP_LNKSTS 0x0004 /* link status */
+#define PHY_SUP_LINK 0x0004 /* link status */
+#define PHY_SUP_DUPLEX 0x0002 /* 1 == full-duplex */
#define NSGPHY_PHYSUP_DUPSTS 0x0002 /* duplex status 1 == full */
#define NSGPHY_PHYSUP_10BT 0x0001 /* 10baseT resolved */