NetBSD Problem Report #27379

From QFH02545@nifty.com  Sat Oct 23 08:28:20 2004
Return-Path: <QFH02545@nifty.com>
Received: from mail503.nifty.com (mail503.nifty.com [202.248.37.211])
	by narn.netbsd.org (Postfix) with ESMTP id 90415251ED6
	for <gnats-bugs@gnats.NetBSD.org>; Sat, 23 Oct 2004 08:28:19 +0000 (UTC)
Message-Id: <pwtxh7sa9.wl@that.nifty.com>
Date: Sat, 23 Oct 2004 17:27:58 +0900
From: HITOSHI Osada <QFH02545@nifty.com>
To: gnats-bugs@gnats.NetBSD.org
Subject: flow control support for ex(4)

>Number:         27379
>Category:       kern
>Synopsis:       flow control support for ex(4)
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    kern-bug-people
>State:          open
>Class:          change-request
>Submitter-Id:   net
>Arrival-Date:   Sat Oct 23 08:29:00 +0000 2004
>Closed-Date:    
>Last-Modified:  Fri Jun 09 10:30:01 +0000 2017
>Originator:     HITOSHI Osada
>Release:        NetBSD 2.99.10 (2004/10/23)
>Organization:
>Environment:
System: NetBSD that 2.99.10 NetBSD 2.99.10 (TIGERMPX) #0: Fri Oct 22 17:43:14 JST 2004 that@that:/sys/arch/i386/compile/TIGERMPX i386
Architecture: i386
Machine: i386

>Description:
	I wrote a patch for ex(4) to support flow control(RXPAUSE only).
	Tested on my TigerMPX(3c920).

>How-To-Repeat:

>Fix:
	Here is a patch. 

Index: elinkxl.c
===================================================================
RCS file: /Sources/NetBSD-rep/netbsd/src/sys/dev/ic/elinkxl.c,v
retrieving revision 1.1.1.3
diff -u -r1.1.1.3 elinkxl.c
--- elinkxl.c	30 Sep 2004 07:38:42 -0000	1.1.1.3
+++ elinkxl.c	23 Oct 2004 08:20:40 -0000
@@ -407,7 +407,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);
@@ -858,16 +859,18 @@
 	bus_space_tag_t iot = sc->sc_iot;
 	bus_space_handle_t ioh = sc->sc_ioh;
 	u_int32_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
@@ -951,7 +954,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;
@@ -1379,6 +1387,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;
@@ -1887,16 +1914,32 @@
 	struct device *v;
 {
 	struct ex_softc *sc = (struct ex_softc *)v;
+	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_int16_t mctl;
+	u_int phy_flowflags;

 	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: /Sources/NetBSD-rep/netbsd/src/sys/dev/ic/elinkxlreg.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -u -r1.1.1.1 -r1.2
--- elinkxlreg.h	10 May 2004 09:07:43 -0000	1.1.1.1
+++ elinkxlreg.h	18 Oct 2004 16:12:58 -0000	1.2
@@ -327,3 +327,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: /Sources/NetBSD-rep/netbsd/src/sys/dev/ic/elinkxlvar.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -u -r1.1.1.1 -r1.2
--- elinkxlvar.h	10 May 2004 09:07:43 -0000	1.1.1.1
+++ elinkxlvar.h	18 Oct 2004 16:12:58 -0000	1.2
@@ -122,6 +122,8 @@
 #if NRND > 0
 	rndsource_element_t rnd_source;
 #endif
+	/* 802.3x flow control (90xB and later, CONF_MII) */
+	int	ex_flowflags;

 	/* power management hooks */
 	int (*enable) __P((struct ex_softc *));
>Release-Note:
>Audit-Trail:
From: coypu@sdf.org
To: gnats-bugs@netbsd.org
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--

>Unformatted:
 >Quarter:
 >Keywords:
 >Date-Required:

NetBSD Home
NetBSD PR Database Search

(Contact us) $NetBSD: query-full-pr,v 1.39 2013/11/01 18:47:49 spz Exp $
$NetBSD: gnats_config.sh,v 1.8 2006/05/07 09:23:38 tsutsui Exp $
Copyright © 1994-2007 The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.