NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: kern/27379: flow control support for ex(4)
The following reply was made to PR kern/27379; it has been noted by GNATS.
From: coypu%sdf.org@localhost
To: gnats-bugs%netbsd.org@localhost
Cc:
Subject: Re: kern/27379: flow control support for ex(4)
Date: Fri, 9 Jun 2017 10:17:03 +0000
--envbJBWh7q8WU6mo
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Updated but untested diff against 8.99.1.
--envbJBWh7q8WU6mo
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="ex.diff"
? .elinkxl.c.swp
? .elinkxlvar.h.swp
? .sl811hs.c.swp
Index: elinkxl.c
===================================================================
RCS file: /cvsroot/src/sys/dev/ic/elinkxl.c,v
retrieving revision 1.121
diff -u -r1.121 elinkxl.c
--- elinkxl.c 20 Feb 2017 07:43:29 -0000 1.121
+++ elinkxl.c 8 Jun 2017 16:34:05 -0000
@@ -388,7 +388,8 @@
ex_set_xcvr(sc, val);
mii_attach(sc->sc_dev, &sc->ex_mii, 0xffffffff,
- MII_PHY_ANY, MII_OFFSET_ANY, 0);
+ MII_PHY_ANY, MII_OFFSET_ANY,
+ (sc->ex_conf & EX_CONF_90XB) ? MIIF_DOPAUSE : 0);
if (LIST_FIRST(&sc->ex_mii.mii_phys) == NULL) {
ifmedia_add(&sc->ex_mii.mii_media, IFM_ETHER|IFM_NONE,
0, NULL);
@@ -893,17 +894,21 @@
bus_space_tag_t iot = sc->sc_iot;
bus_space_handle_t ioh = sc->sc_ioh;
uint32_t configreg;
+ u_int16_t mctl = 0;
- if (((sc->ex_conf & EX_CONF_MII) &&
- (sc->ex_mii.mii_media_active & IFM_FDX))
- || (!(sc->ex_conf & EX_CONF_MII) &&
- (sc->ex_mii.mii_media.ifm_media & IFM_FDX))) {
- bus_space_write_2(iot, ioh, ELINK_W3_MAC_CONTROL,
- MAC_CONTROL_FDX);
+ if (sc->ex_conf & EX_CONF_MII) {
+ if (sc->ex_mii.mii_media_active & IFM_FDX)
+ mctl |= MAC_CONTROL_FDX;
+ if (sc->ex_flowflags & (IFM_FLOW|IFM_ETH_RXPAUSE))
+ mctl |= ELINK_MAC_FLOWENABLE;
} else {
- bus_space_write_2(iot, ioh, ELINK_W3_MAC_CONTROL, 0);
+ if (sc->ex_mii.mii_media.ifm_media & IFM_FDX)
+ mctl |= MAC_CONTROL_FDX;
}
+ bus_space_write_2(iot, ioh, ELINK_W3_MAC_CONTROL, mctl);
+
+
/*
* If the device has MII, select it, and then tell the
* PHY which media to use.
@@ -984,7 +989,12 @@
if (sc->ex_conf & EX_CONF_MII) {
mii_pollstat(&sc->ex_mii);
req->ifm_status = sc->ex_mii.mii_media_status;
- req->ifm_active = sc->ex_mii.mii_media_active;
+ if (sc->ex_conf & EX_CONF_90XB) {
+ req->ifm_active = (sc->ex_mii.mii_media_active & ~IFM_ETH_FMASK) |
+ sc->ex_flowflags;
+ } else {
+ req->ifm_active = sc->ex_mii.mii_media_active;
+ }
} else {
GO_WINDOW(4);
req->ifm_status = IFM_AVALID;
@@ -1449,6 +1459,25 @@
switch (cmd) {
case SIOCSIFMEDIA:
+ if ((sc->ex_conf & EX_CONF_MII) && (sc->ex_conf & EX_CONF_90XB)) {
+ if (IFM_SUBTYPE(ifr->ifr_media) == IFM_AUTO ||
+ (ifr->ifr_media & IFM_FDX) == 0) {
+ ifr->ifr_media &= ~IFM_ETH_FMASK;
+ }
+ if (IFM_SUBTYPE(ifr->ifr_media) != IFM_AUTO) {
+ if ((ifr->ifr_media & IFM_ETH_FMASK) == IFM_FLOW) {
+ /* RXPAUSE only */
+ ifr->ifr_media |= IFM_ETH_RXPAUSE;
+ }
+ if (ifr->ifr_media & IFM_FLOW) {
+ sc->ex_flowflags =
+ ifr->ifr_media & (IFM_FLOW|IFM_ETH_RXPAUSE);
+ } else {
+ sc->ex_flowflags = 0;
+ }
+ }
+ }
+ /* FALLTHROUGH */
case SIOCGIFMEDIA:
error = ifmedia_ioctl(ifp, ifr, &sc->ex_mii.mii_media, cmd);
break;
@@ -1927,16 +1956,32 @@
ex_mii_statchg(struct ifnet *ifp)
{
struct ex_softc *sc = ifp->if_softc;
+ struct mii_data *mii = &sc->ex_mii;
bus_space_tag_t iot = sc->sc_iot;
bus_space_handle_t ioh = sc->sc_ioh;
- int mctl;
+ u_int phy_flowflags;
+ u_int16_t mctl;
GO_WINDOW(3);
mctl = bus_space_read_2(iot, ioh, ELINK_W3_MAC_CONTROL);
- if (sc->ex_mii.mii_media_active & IFM_FDX)
+ if (mii->mii_media_active & IFM_FDX)
mctl |= MAC_CONTROL_FDX;
else
mctl &= ~MAC_CONTROL_FDX;
+ /* 802.3x flow control */
+ if ((sc->ex_conf & EX_CONF_MII) && (sc->ex_conf & EX_CONF_90XB)) {
+ phy_flowflags = mii->mii_media_active & (IFM_FLOW|IFM_ETH_RXPAUSE);
+ mii->mii_media_active &= ~IFM_ETH_FMASK;
+ if ((IFM_SUBTYPE(mii->mii_media.ifm_cur->ifm_media) == IFM_AUTO) &&
+ (phy_flowflags != sc->ex_flowflags)) {
+ sc->ex_flowflags = phy_flowflags;
+ }
+ if (sc->ex_flowflags & (IFM_FLOW|IFM_ETH_RXPAUSE))
+ mctl |= ELINK_MAC_FLOWENABLE;
+ else
+ mctl &= ~ELINK_MAC_FLOWENABLE;
+ }
+
bus_space_write_2(iot, ioh, ELINK_W3_MAC_CONTROL, mctl);
GO_WINDOW(1); /* back to operating window */
}
Index: elinkxlreg.h
===================================================================
RCS file: /cvsroot/src/sys/dev/ic/elinkxlreg.h,v
retrieving revision 1.15
diff -u -r1.15 elinkxlreg.h
--- elinkxlreg.h 28 Apr 2008 20:23:49 -0000 1.15
+++ elinkxlreg.h 8 Jun 2017 16:34:05 -0000
@@ -332,3 +332,6 @@
#define EX_UPD_ERR 0x001f4000 /* Errors we check for */
#define EX_UPD_ERR_VLAN 0x000f0000 /* same for 802.1q */
+
+/* 802.3x flow control flag (in MAC Control Register) */
+#define ELINK_MAC_FLOWENABLE 0x100
Index: elinkxlvar.h
===================================================================
RCS file: /cvsroot/src/sys/dev/ic/elinkxlvar.h,v
retrieving revision 1.25
diff -u -r1.25 elinkxlvar.h
--- elinkxlvar.h 13 Apr 2015 16:33:24 -0000 1.25
+++ elinkxlvar.h 8 Jun 2017 16:34:05 -0000
@@ -107,6 +107,9 @@
krndsource_t rnd_source;
+ /* 802.3x flow control (90xB and later, CONF_MII) */
+ int ex_flowflags;
+
/* power management hooks */
int (*enable)(struct ex_softc *);
void (*disable)(struct ex_softc *);
--envbJBWh7q8WU6mo--
Home |
Main Index |
Thread Index |
Old Index