summaryrefslogtreecommitdiff
path: root/sys/dev/mii
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2006-12-28 09:24:28 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2006-12-28 09:24:28 +0000
commitaaff2c75f5c51ba1af4dd9848404ae90457b83ef (patch)
tree7ebd13692d29f548f009e26a237c60d68010c01c /sys/dev/mii
parent58236cdba179c22d89bc3310c113a5fb6206d482 (diff)
Add function to detect flow control status. From NetBSD.
ok brad@
Diffstat (limited to 'sys/dev/mii')
-rw-r--r--sys/dev/mii/mii_physubr.c48
-rw-r--r--sys/dev/mii/miivar.h4
2 files changed, 50 insertions, 2 deletions
diff --git a/sys/dev/mii/mii_physubr.c b/sys/dev/mii/mii_physubr.c
index 1ef0455bc73..0fe41652334 100644
--- a/sys/dev/mii/mii_physubr.c
+++ b/sys/dev/mii/mii_physubr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mii_physubr.c,v 1.29 2006/12/15 21:47:27 reyk Exp $ */
+/* $OpenBSD: mii_physubr.c,v 1.30 2006/12/28 09:24:27 kettenis Exp $ */
/* $NetBSD: mii_physubr.c,v 1.20 2001/04/13 23:30:09 thorpej Exp $ */
/*-
@@ -519,6 +519,52 @@ mii_phy_match(const struct mii_attach_args *ma, const struct mii_phydesc *mpd)
}
/*
+ * Return the flow control status flag from MII_ANAR & MII_ANLPAR.
+ */
+int
+mii_phy_flowstatus(struct mii_softc *sc)
+{
+ int anar, anlpar;
+
+ if ((sc->mii_flags & MIIF_DOPAUSE) == 0)
+ return (0);
+
+ anar = PHY_READ(sc, MII_ANAR);
+ anlpar = PHY_READ(sc, MII_ANLPAR);
+
+ if ((anar & ANAR_X_PAUSE_SYM) & (anlpar & ANLPAR_X_PAUSE_SYM))
+ return (IFM_FLOW|IFM_ETH_TXPAUSE|IFM_ETH_RXPAUSE);
+
+ if ((anar & ANAR_X_PAUSE_SYM) == 0) {
+ if ((anar & ANAR_X_PAUSE_ASYM) &&
+ ((anlpar &
+ ANLPAR_X_PAUSE_TOWARDS) == ANLPAR_X_PAUSE_TOWARDS))
+ return (IFM_FLOW|IFM_ETH_TXPAUSE);
+ else
+ return (0);
+ }
+
+ if ((anar & ANAR_X_PAUSE_ASYM) == 0) {
+ if (anlpar & ANLPAR_X_PAUSE_SYM)
+ return (IFM_FLOW|IFM_ETH_TXPAUSE|IFM_ETH_RXPAUSE);
+ else
+ return (0);
+ }
+
+ switch ((anlpar & ANLPAR_X_PAUSE_TOWARDS)) {
+ case ANLPAR_X_PAUSE_NONE:
+ return (0);
+
+ case ANLPAR_X_PAUSE_ASYM:
+ return (IFM_FLOW|IFM_ETH_RXPAUSE);
+
+ default:
+ return (IFM_FLOW|IFM_ETH_RXPAUSE|IFM_ETH_TXPAUSE);
+ }
+ /* NOTREACHED */
+}
+
+/*
* Given an ifmedia word, return the corresponding ANAR value.
*/
int
diff --git a/sys/dev/mii/miivar.h b/sys/dev/mii/miivar.h
index 8f986f05692..2e750a03f0f 100644
--- a/sys/dev/mii/miivar.h
+++ b/sys/dev/mii/miivar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: miivar.h,v 1.26 2005/11/06 09:27:19 brad Exp $ */
+/* $OpenBSD: miivar.h,v 1.27 2006/12/28 09:24:27 kettenis Exp $ */
/* $NetBSD: miivar.h,v 1.17 2000/03/06 20:56:57 thorpej Exp $ */
/*-
@@ -269,6 +269,8 @@ void mii_phy_status(struct mii_softc *);
void mii_phy_update(struct mii_softc *, int);
int mii_phy_statusmsg(struct mii_softc *);
+int mii_phy_flowstatus(struct mii_softc *);
+
void ukphy_status(struct mii_softc *);
#endif /* _KERNEL */