PERFORCE change 140397 for review

John Birrell jb at FreeBSD.org
Tue Apr 22 09:53:36 UTC 2008


http://perforce.freebsd.org/chv.cgi?CH=140397

Change 140397 by jb at freebsd3 on 2008/04/22 09:52:57

	IF7

Affected files ...

.. //depot/projects/dtrace7/src/lib/libc/stdlib/strfmon.c#2 integrate
.. //depot/projects/dtrace7/src/lib/libthr/thread/thr_mutexattr.c#2 integrate
.. //depot/projects/dtrace7/src/share/man/man4/nfe.4#3 integrate
.. //depot/projects/dtrace7/src/sys/dev/mii/ip1000phy.c#2 integrate
.. //depot/projects/dtrace7/src/sys/dev/mii/ip1000phyreg.h#2 integrate
.. //depot/projects/dtrace7/src/sys/dev/mii/miidevs#3 integrate
.. //depot/projects/dtrace7/src/sys/dev/mii/rgephy.c#2 integrate
.. //depot/projects/dtrace7/src/sys/dev/re/if_re.c#6 integrate
.. //depot/projects/dtrace7/src/sys/pci/if_rl.c#5 integrate
.. //depot/projects/dtrace7/src/sys/pci/if_rlreg.h#4 integrate

Differences ...

==== //depot/projects/dtrace7/src/lib/libc/stdlib/strfmon.c#2 (text+ko) ====

@@ -26,7 +26,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/lib/libc/stdlib/strfmon.c,v 1.15 2005/09/12 19:52:42 stefanf Exp $");
+__FBSDID("$FreeBSD: src/lib/libc/stdlib/strfmon.c,v 1.15.2.1 2008/04/22 08:05:38 ru Exp $");
 
 #include <sys/types.h>
 #include <ctype.h>
@@ -67,6 +67,8 @@
 	while (isdigit((unsigned char)*fmt)) {			\
 		VAR *= 10;					\
 		VAR += *fmt - '0';				\
+		if (VAR < 0)					\
+			goto e2big_error;			\
 		fmt++;						\
 	}							\
 } while (0)
@@ -187,7 +189,7 @@
 			/* Do we have enough space to put number with
 			 * required width ?
 			 */
-			if (dst + width >= s + maxsize)
+			if ((unsigned int)width >= maxsize - (dst - s))
 				goto e2big_error;
 		}
 
@@ -196,6 +198,8 @@
 			if (!isdigit((unsigned char)*++fmt))
 				goto format_error;
 			GET_NUMBER(left_prec);
+			if ((unsigned int)left_prec >= maxsize - (dst - s))
+				goto e2big_error;
 		}
 
 		/* Right precision */
@@ -203,6 +207,9 @@
 			if (!isdigit((unsigned char)*++fmt))
 				goto format_error;
 			GET_NUMBER(right_prec);
+			if ((unsigned int)right_prec >= maxsize - (dst - s) -
+			    left_prec)
+				goto e2big_error;
 		}
 
 		/* Conversion Characters */
@@ -218,6 +225,8 @@
 				goto format_error;
 		}
 
+		if (currency_symbol != NULL)
+			free(currency_symbol);
 		if (flags & USE_INTL_CURRENCY) {
 			currency_symbol = strdup(lc->int_curr_symbol);
 			if (currency_symbol != NULL)
@@ -246,6 +255,8 @@
 				pad_size = 0;
 		}
 
+		if (asciivalue != NULL)
+			free(asciivalue);
 		asciivalue = __format_grouped_double(value, &flags,
 				left_prec, right_prec, pad_char);
 		if (asciivalue == NULL)
@@ -535,12 +546,11 @@
 
 	/* make sure that we've enough space for result string */
 	bufsize = strlen(avalue)*2+1;
-	rslt = malloc(bufsize);
+	rslt = calloc(1, bufsize);
 	if (rslt == NULL) {
 		free(avalue);
 		return (NULL);
 	}
-	memset(rslt, 0, bufsize);
 	bufend = rslt + bufsize - 1;	/* reserve space for trailing '\0' */
 
 	/* skip spaces at beggining */

==== //depot/projects/dtrace7/src/lib/libthr/thread/thr_mutexattr.c#2 (text+ko) ====

@@ -26,7 +26,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/lib/libthr/thread/thr_mutexattr.c,v 1.7 2007/01/12 07:26:20 imp Exp $
+ * $FreeBSD: src/lib/libthr/thread/thr_mutexattr.c,v 1.7.2.1 2008/04/22 01:28:15 davidxu Exp $
  */
 
 /*
@@ -132,8 +132,7 @@
 {
 	int	ret;
 	if (attr == NULL || *attr == NULL || type >= PTHREAD_MUTEX_TYPE_MAX) {
-		errno = EINVAL;
-		ret = -1;
+		ret = EINVAL;
 	} else {
 		(*attr)->m_type = type;
 		ret = 0;

==== //depot/projects/dtrace7/src/share/man/man4/nfe.4#3 (text+ko) ====

@@ -14,9 +14,9 @@
 .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 .\"
-.\" $FreeBSD: src/share/man/man4/nfe.4,v 1.8.2.1 2007/12/02 08:45:57 remko Exp $
+.\" $FreeBSD: src/share/man/man4/nfe.4,v 1.8.2.2 2008/04/22 06:19:29 yongari Exp $
 .\"
-.Dd Nov 27, 2007
+.Dd April 16, 2008
 .Dt NFE 4
 .Os
 .Sh NAME
@@ -43,7 +43,7 @@
 driver supports PCI Ethernet adapters based on the NVIDIA
 nForce Media and Communications Processors (MCP), such as
 the nForce, nForce 2, nForce 3, CK804, MCP04, MCP51, MCP55,
-MCP61, MCP65 and MCP67 Ethernet controller chips.
+MCP61, MCP65, MCP67 and MCP73 Ethernet controller chips.
 .Pp
 Supported features include (hardware support provided):
 .Pp
@@ -116,6 +116,8 @@
 .It
 NVIDIA nForce MCP67 Networking Adapter
 .It
+NVIDIA nForce MCP73 Networking Adapter
+.It
 NVIDIA nForce2 MCP2 Networking Adapter
 .It
 NVIDIA nForce2 400 MCP4 Networking Adapter

==== //depot/projects/dtrace7/src/sys/dev/mii/ip1000phy.c#2 (text+ko) ====

@@ -27,10 +27,10 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/dev/mii/ip1000phy.c,v 1.2 2006/12/02 15:32:33 marius Exp $");
+__FBSDID("$FreeBSD: src/sys/dev/mii/ip1000phy.c,v 1.2.2.1 2008/04/22 06:35:37 yongari Exp $");
 
 /*
- * Driver for the IC Plus IP1000A 10/100/1000 PHY.
+ * Driver for the IC Plus IP1000A/IP1001 10/100/1000 PHY.
  */
 
 #include <sys/param.h>
@@ -57,6 +57,12 @@
 static int ip1000phy_probe(device_t);
 static int ip1000phy_attach(device_t);
 
+struct ip1000phy_softc {
+	struct mii_softc mii_sc;
+	int model;
+	int revision;
+};
+
 static device_method_t ip1000phy_methods[] = {
 	/* device interface */
 	DEVMETHOD(device_probe,		ip1000phy_probe),
@@ -82,6 +88,7 @@
 
 static const struct mii_phydesc ip1000phys[] = {
 	MII_PHY_DESC(ICPLUS, IP1000A),
+	MII_PHY_DESC(ICPLUS, IP1001),
 	MII_PHY_END
 };
 
@@ -95,11 +102,13 @@
 static int
 ip1000phy_attach(device_t dev)
 {
+	struct ip1000phy_softc *isc;
 	struct mii_softc *sc;
 	struct mii_attach_args *ma;
 	struct mii_data *mii;
 
-	sc = device_get_softc(dev);
+	isc = device_get_softc(dev);
+	sc = &isc->mii_sc;
 	ma = device_get_ivars(dev);
 	sc->mii_dev = device_get_parent(dev);
 	mii = device_get_softc(sc->mii_dev);
@@ -114,6 +123,9 @@
 
 	mii->mii_instance++;
 
+	isc->model = MII_MODEL(ma->mii_id2);
+	isc->revision = MII_REV(ma->mii_id2);
+
 	device_printf(dev, " ");
 
 #define	ADD(m, c)	ifmedia_add(&mii->mii_media, (m), (c), NULL)
@@ -302,10 +314,13 @@
 static void
 ip1000phy_status(struct mii_softc *sc)
 {
+	struct ip1000phy_softc *isc;
 	struct mii_data *mii = sc->mii_pdata;
 	uint32_t bmsr, bmcr, stat;
 	uint32_t ar, lpar;
 
+	isc = (struct ip1000phy_softc *)sc;
+
 	mii->mii_media_status = IFM_AVALID;
 	mii->mii_media_active = IFM_ETHER;
 
@@ -326,25 +341,44 @@
                 }
         }
 
-	stat = PHY_READ(sc, STGE_PhyCtrl);
-	switch (PC_LinkSpeed(stat)) {
-	case PC_LinkSpeed_Down:
-		mii->mii_media_active |= IFM_NONE;
-		return;
-	case PC_LinkSpeed_10:
-		mii->mii_media_active |= IFM_10_T;
-		break;
-	case PC_LinkSpeed_100:
-		mii->mii_media_active |= IFM_100_TX;
-		break;
-	case PC_LinkSpeed_1000:
-		mii->mii_media_active |= IFM_1000_T;
-		break;
+	if (isc->model == MII_MODEL_ICPLUS_IP1001) {
+		stat = PHY_READ(sc, IP1000PHY_LSR);
+		switch (stat & IP1000PHY_LSR_SPEED_MASK) {
+		case IP1000PHY_LSR_SPEED_10:
+			mii->mii_media_active |= IFM_10_T;
+			break;
+		case IP1000PHY_LSR_SPEED_100:
+			mii->mii_media_active |= IFM_100_TX;
+			break;
+		case IP1000PHY_LSR_SPEED_1000:
+			mii->mii_media_active |= IFM_1000_T;
+			break;
+		}
+		if ((stat & IP1000PHY_LSR_FULL_DUPLEX) != 0)
+			mii->mii_media_active |= IFM_FDX;
+		else
+			mii->mii_media_active |= IFM_HDX;
+	} else {
+		stat = PHY_READ(sc, STGE_PhyCtrl);
+		switch (PC_LinkSpeed(stat)) {
+		case PC_LinkSpeed_Down:
+			mii->mii_media_active |= IFM_NONE;
+			return;
+		case PC_LinkSpeed_10:
+			mii->mii_media_active |= IFM_10_T;
+			break;
+		case PC_LinkSpeed_100:
+			mii->mii_media_active |= IFM_100_TX;
+			break;
+		case PC_LinkSpeed_1000:
+			mii->mii_media_active |= IFM_1000_T;
+			break;
+		}
+		if ((stat & PC_PhyDuplexStatus) != 0)
+			mii->mii_media_active |= IFM_FDX;
+		else
+			mii->mii_media_active |= IFM_HDX;
 	}
-	if ((stat & PC_PhyDuplexStatus) != 0)
-		mii->mii_media_active |= IFM_FDX;
-	else
-		mii->mii_media_active |= IFM_HDX;
 
 	ar = PHY_READ(sc, IP1000PHY_MII_ANAR);
 	lpar = PHY_READ(sc, IP1000PHY_MII_ANLPAR);
@@ -410,10 +444,12 @@
 static void
 ip1000phy_reset(struct mii_softc *sc)
 {
+	struct ip1000phy_softc *isc;
 	struct stge_softc *stge_sc;
 	struct mii_data *mii;
 	uint32_t reg;
 
+	isc = (struct ip1000phy_softc *)sc;
 	mii_phy_reset(sc);
 
 	/* clear autoneg/full-duplex as we don't want it after reset */
@@ -426,7 +462,8 @@
 	 * XXX There should be more general way to pass PHY specific
 	 * data via mii interface.
 	 */
-	if (strcmp(mii->mii_ifp->if_dname, "stge") == 0) {
+	if (isc->model == MII_MODEL_ICPLUS_IP1000A &&
+	     strcmp(mii->mii_ifp->if_dname, "stge") == 0) {
 		stge_sc = mii->mii_ifp->if_softc;
 		if (stge_sc->sc_rev >= 0x40 && stge_sc->sc_rev <= 0x4e)
 			ip1000phy_load_dspcode(sc);

==== //depot/projects/dtrace7/src/sys/dev/mii/ip1000phyreg.h#2 (text+ko) ====

@@ -24,7 +24,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/sys/dev/mii/ip1000phyreg.h,v 1.1 2006/07/25 00:16:09 yongari Exp $
+ * $FreeBSD: src/sys/dev/mii/ip1000phyreg.h,v 1.1.4.1 2008/04/22 06:35:37 yongari Exp $
  */
 
 #ifndef	_DEV_MII_IP1000PHYREG_H_
@@ -138,4 +138,49 @@
 #define	IP1000PHY_EXTSTS_1000X		0x4000
 #define	IP1000PHY_EXTSTS_1000X_FDX	0x8000
 
+/* PHY specific control & status register. IP1001 only. */
+#define	IP1000PHY_SCSR			0x10
+#define	IP1000PHY_SCSR_RXPHASE_SEL	0x0001
+#define	IP1000PHY_SCSR_TXPHASE_SEL	0x0002
+#define	IP1000PHY_SCSR_REPEATOR_MODE	0x0004
+#define	IP1000PHY_SCSR_RESERVED1_DEF	0x0008
+#define	IP1000PHY_SCSR_RXCLK_DRV_MASK	0x0060
+#define	IP1000PHY_SCSR_RXCLK_DRV_DEF	0x0040
+#define	IP1000PHY_SCSR_RXD_DRV_MASK	0x0180
+#define	IP1000PHY_SCSR_RXD_DRV_DEF	0x0100
+#define	IP1000PHY_SCSR_JABBER_ENB	0x0200
+#define	IP1000PHY_SCSR_HEART_BEAT_ENB	0x0400
+#define	IP1000PHY_SCSR_DOWNSHIFT_ENB	0x0800
+#define	IP1000PHY_SCSR_RESERVED2_DEF	0x1000
+#define	IP1000PHY_SCSR_LED_DRV_4MA	0x0000
+#define	IP1000PHY_SCSR_LED_DRV_8MA	0x2000
+#define	IP1000PHY_SCSR_LED_MODE_MASK	0xC000
+#define	IP1000PHY_SCSR_LED_MODE_DEF	0x0000
+
+/* PHY link status register. IP1001 only. */
+#define	IP1000PHY_LSR			0x11
+#define	IP1000PHY_LSR_JABBER_DET	0x0200
+#define	IP1000PHY_LSR_APS_SLEEP		0x0400
+#define	IP1000PHY_LSR_MDIX		0x0800
+#define	IP1000PHY_LSR_FULL_DUPLEX	0x1000
+#define	IP1000PHY_LSR_SPEED_10		0x0000
+#define	IP1000PHY_LSR_SPEED_100		0x2000
+#define	IP1000PHY_LSR_SPEED_1000	0x4000
+#define	IP1000PHY_LSR_SPEED_MASK	0x6000
+#define	IP1000PHY_LSR_LINKUP		0x8000
+
+/* PHY specific control register 2. IP1001 only. */
+#define	IP1000PHY_SCR
+#define	IP1000PHY_SCR_SEW_RATE_MASK	0x0003
+#define	IP1000PHY_SCR_SEW_RATE_DEF	0x0003
+#define	IP1000PHY_SCR_AUTO_XOVER	0x0004
+#define	IP1000PHY_SCR_SPEED_10_100_ENB	0x0040
+#define	IP1000PHY_SCR_FIFO_LATENCY_2	0x0000
+#define	IP1000PHY_SCR_FIFO_LATENCY_3	0x0080
+#define	IP1000PHY_SCR_FIFO_LATENCY_4	0x0100
+#define	IP1000PHY_SCR_FIFO_LATENCY_5	0x0180
+#define	IP1000PHY_SCR_MDIX_ENB		0x0200
+#define	IP1000PHY_SCR_RESERVED_DEF	0x0400
+#define	IP1000PHY_SCR_APS_ON		0x0800
+
 #endif	/* _DEV_MII_IP1000PHYREG_H_ */

==== //depot/projects/dtrace7/src/sys/dev/mii/miidevs#3 (text+ko) ====

@@ -1,4 +1,4 @@
-$FreeBSD: src/sys/dev/mii/miidevs,v 1.46.2.3 2008/03/17 18:23:44 jhb Exp $
+$FreeBSD: src/sys/dev/mii/miidevs,v 1.46.2.4 2008/04/22 06:35:37 yongari Exp $
 /*$NetBSD: miidevs,v 1.6 1999/05/14 11:37:30 drochner Exp $*/
 
 /*-
@@ -156,6 +156,7 @@
 /* IC Plus Corp. PHYs */
 model ICPLUS IP101		0x0005 IC Plus 10/100 PHY
 model ICPLUS IP1000A		0x0008 IC Plus 10/100/1000 media interface
+model ICPLUS IP1001		0x0019 IC Plus IP1001 10/100/1000 media interface
 
 /* Intel PHYs */
 model xxINTEL I82553AB		0x0000 i83553 10/100 media interface

==== //depot/projects/dtrace7/src/sys/dev/mii/rgephy.c#2 (text+ko) ====

@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/dev/mii/rgephy.c,v 1.15.2.2 2007/11/05 01:39:25 yongari Exp $");
+__FBSDID("$FreeBSD: src/sys/dev/mii/rgephy.c,v 1.15.2.3 2008/04/22 06:25:11 yongari Exp $");
 
 /*
  * Driver for the RealTek 8169S/8110S/8211B internal 10/100/1000 PHY.
@@ -367,6 +367,11 @@
 	bmsr = PHY_READ(sc, RGEPHY_MII_BMSR);
 
 	bmcr = PHY_READ(sc, RGEPHY_MII_BMCR);
+	if (bmcr & RGEPHY_BMCR_ISO) {
+		mii->mii_media_active |= IFM_NONE;
+		mii->mii_media_status = 0;
+		return;
+	}
 
 	if (bmcr & RGEPHY_BMCR_LOOP)
 		mii->mii_media_active |= IFM_LOOP;

==== //depot/projects/dtrace7/src/sys/dev/re/if_re.c#6 (text+ko) ====

@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/dev/re/if_re.c,v 1.95.2.5 2008/03/13 07:50:47 yongari Exp $");
+__FBSDID("$FreeBSD: src/sys/dev/re/if_re.c,v 1.95.2.18 2008/04/22 06:14:56 yongari Exp $");
 
 /*
  * RealTek 8139C+/8169/8169S/8110S/8168/8111/8101E PCI NIC driver
@@ -146,6 +146,8 @@
 #include <dev/pci/pcireg.h>
 #include <dev/pci/pcivar.h>
 
+#include <pci/if_rlreg.h>
+
 MODULE_DEPEND(re, pci, 1, 1, 1);
 MODULE_DEPEND(re, ether, 1, 1, 1);
 MODULE_DEPEND(re, miibus, 1, 1, 1);
@@ -158,10 +160,8 @@
  */
 #define RE_USEIOSPACE
 
-#include <pci/if_rlreg.h>
-
 /* Tunables. */
-static int msi_disable = 0;
+static int msi_disable = 1;
 TUNABLE_INT("hw.re.msi_disable", &msi_disable);
 
 #define RE_CSUM_FEATURES    (CSUM_IP | CSUM_TCP | CSUM_UDP)
@@ -201,8 +201,7 @@
 	{ LINKSYS_VENDORID, LINKSYS_DEVICEID_EG1032, RL_HWREV_8169S,
 		"Linksys EG1032 (RTL8169S) Gigabit Ethernet" },
 	{ USR_VENDORID, USR_DEVICEID_997902, RL_HWREV_8169S,
-		"US Robotics 997902 (RTL8169S) Gigabit Ethernet" },
-	{ 0, 0, 0, NULL }
+		"US Robotics 997902 (RTL8169S) Gigabit Ethernet" }
 };
 
 static struct rl_hwrev re_hwrevs[] = {
@@ -233,13 +232,13 @@
 static int re_attach		(device_t);
 static int re_detach		(device_t);
 
-static int re_encap		(struct rl_softc *, struct mbuf **, int *);
+static int re_encap		(struct rl_softc *, struct mbuf **);
 
 static void re_dma_map_addr	(void *, bus_dma_segment_t *, int, int);
-static void re_dma_map_desc	(void *, bus_dma_segment_t *, int,
-				    bus_size_t, int);
 static int re_allocmem		(device_t, struct rl_softc *);
-static int re_newbuf		(struct rl_softc *, int, struct mbuf *);
+static __inline void re_discard_rxbuf
+				(struct rl_softc *, int);
+static int re_newbuf		(struct rl_softc *, int);
 static int re_rx_list_init	(struct rl_softc *);
 static int re_tx_list_init	(struct rl_softc *);
 #ifdef RE_FIXUP_RX
@@ -280,6 +279,8 @@
 
 static void re_setmulti		(struct rl_softc *);
 static void re_reset		(struct rl_softc *);
+static void re_setwol		(struct rl_softc *);
+static void re_clrwol		(struct rl_softc *);
 
 #ifdef RE_DIAG
 static int re_diag		(struct rl_softc *);
@@ -849,14 +850,14 @@
 	bus_dmamap_sync(sc->rl_ldata.rl_rx_list_tag,
 	    sc->rl_ldata.rl_rx_list_map,
 	    BUS_DMASYNC_POSTREAD);
-	bus_dmamap_sync(sc->rl_ldata.rl_mtag,
-	    sc->rl_ldata.rl_rx_dmamap[0],
-	    BUS_DMASYNC_POSTWRITE);
-	bus_dmamap_unload(sc->rl_ldata.rl_mtag,
-	    sc->rl_ldata.rl_rx_dmamap[0]);
+	bus_dmamap_sync(sc->rl_ldata.rl_rx_mtag,
+	    sc->rl_ldata.rl_rx_desc[0].rx_dmamap,
+	    BUS_DMASYNC_POSTREAD);
+	bus_dmamap_unload(sc->rl_ldata.rl_rx_mtag,
+	    sc->rl_ldata.rl_rx_desc[0].rx_dmamap);
 
-	m0 = sc->rl_ldata.rl_rx_mbuf[0];
-	sc->rl_ldata.rl_rx_mbuf[0] = NULL;
+	m0 = sc->rl_ldata.rl_rx_desc[0].rx_m;
+	sc->rl_ldata.rl_rx_desc[0].rx_m = NULL;
 	eh = mtod(m0, struct ether_header *);
 
 	cur_rx = &sc->rl_ldata.rl_rx_list[0];
@@ -916,133 +917,41 @@
 	device_t		dev;
 {
 	struct rl_type		*t;
-	struct rl_softc		*sc;
-	int			rid;
-	u_int32_t		hwrev;
+	uint16_t		devid, vendor;
+	uint16_t		revid, sdevid;
+	int			i;
+	
+	vendor = pci_get_vendor(dev);
+	devid = pci_get_device(dev);
+	revid = pci_get_revid(dev);
+	sdevid = pci_get_subdevice(dev);
 
-	t = re_devs;
-	sc = device_get_softc(dev);
-
-	while (t->rl_name != NULL) {
-		if ((pci_get_vendor(dev) == t->rl_vid) &&
-		    (pci_get_device(dev) == t->rl_did)) {
+	if (vendor == LINKSYS_VENDORID && devid == LINKSYS_DEVICEID_EG1032) {
+		if (sdevid != LINKSYS_SUBDEVICE_EG1032_REV3) {
 			/*
 			 * Only attach to rev. 3 of the Linksys EG1032 adapter.
-			 * Rev. 2 i supported by sk(4).
+			 * Rev. 2 is supported by sk(4).
 			 */
-			if ((t->rl_vid == LINKSYS_VENDORID) &&
-				(t->rl_did == LINKSYS_DEVICEID_EG1032) &&
-				(pci_get_subdevice(dev) !=
-				LINKSYS_SUBDEVICE_EG1032_REV3)) {
-				t++;
-				continue;
-			}
-
-			/*
-			 * Temporarily map the I/O space
-			 * so we can read the chip ID register.
-			 */
-			rid = RL_RID;
-			sc->rl_res = bus_alloc_resource_any(dev, RL_RES, &rid,
-			    RF_ACTIVE);
-			if (sc->rl_res == NULL) {
-				device_printf(dev,
-				    "couldn't map ports/memory\n");
-				return (ENXIO);
-			}
-			sc->rl_btag = rman_get_bustag(sc->rl_res);
-			sc->rl_bhandle = rman_get_bushandle(sc->rl_res);
-			hwrev = CSR_READ_4(sc, RL_TXCFG) & RL_TXCFG_HWREV;
-			bus_release_resource(dev, RL_RES,
-			    RL_RID, sc->rl_res);
-			if (t->rl_basetype == hwrev) {
-				device_set_desc(dev, t->rl_name);
-				return (BUS_PROBE_DEFAULT);
-			}
+			return (ENXIO);
 		}
-		t++;
 	}
 
-	return (ENXIO);
-}
-
-/*
- * This routine takes the segment list provided as the result of
- * a bus_dma_map_load() operation and assigns the addresses/lengths
- * to RealTek DMA descriptors. This can be called either by the RX
- * code or the TX code. In the RX case, we'll probably wind up mapping
- * at most one segment. For the TX case, there could be any number of
- * segments since TX packets may span multiple mbufs. In either case,
- * if the number of segments is larger than the rl_maxsegs limit
- * specified by the caller, we abort the mapping operation. Sadly,
- * whoever designed the buffer mapping API did not provide a way to
- * return an error from here, so we have to fake it a bit.
- */
-
-static void
-re_dma_map_desc(arg, segs, nseg, mapsize, error)
-	void			*arg;
-	bus_dma_segment_t	*segs;
-	int			nseg;
-	bus_size_t		mapsize;
-	int			error;
-{
-	struct rl_dmaload_arg	*ctx;
-	struct rl_desc		*d = NULL;
-	int			i = 0, idx;
-	u_int32_t		cmdstat;
-	int			totlen = 0;
-
-	if (error)
-		return;
-
-	ctx = arg;
-
-	/* Signal error to caller if there's too many segments */
-	if (nseg > ctx->rl_maxsegs) {
-		ctx->rl_maxsegs = 0;
-		return;
+	if (vendor == RT_VENDORID && devid == RT_DEVICEID_8139) {
+		if (revid != 0x20) {
+			/* 8139, let rl(4) take care of this device. */
+			return (ENXIO);
+		}
 	}
 
-	/*
-	 * Map the segment array into descriptors. Note that we set the
-	 * start-of-frame and end-of-frame markers for either TX or RX, but
-	 * they really only have meaning in the TX case. (In the RX case,
-	 * it's the chip that tells us where packets begin and end.)
-	 * We also keep track of the end of the ring and set the
-	 * end-of-ring bits as needed, and we set the ownership bits
-	 * in all except the very first descriptor. (The caller will
-	 * set this descriptor later when it start transmission or
-	 * reception.)
-	 */
-	idx = ctx->rl_idx;
-	for (;;) {
-		d = &ctx->rl_ring[idx];
-		if (le32toh(d->rl_cmdstat) & RL_RDESC_STAT_OWN) {
-			ctx->rl_maxsegs = 0;
-			return;
+	t = re_devs;
+	for (i = 0; i < sizeof(re_devs) / sizeof(re_devs[0]); i++, t++) {
+		if (vendor == t->rl_vid && devid == t->rl_did) {
+			device_set_desc(dev, t->rl_name);
+			return (BUS_PROBE_DEFAULT);
 		}
-		cmdstat = segs[i].ds_len;
-		totlen += segs[i].ds_len;
-		d->rl_vlanctl = 0;
-		d->rl_bufaddr_lo = htole32(RL_ADDR_LO(segs[i].ds_addr));
-		d->rl_bufaddr_hi = htole32(RL_ADDR_HI(segs[i].ds_addr));
-		if (i == 0)
-			cmdstat |= RL_TDESC_CMD_SOF;
-		else
-			cmdstat |= RL_TDESC_CMD_OWN;
-		if (idx == (RL_RX_DESC_CNT - 1))
-			cmdstat |= RL_TDESC_CMD_EOR;
-		d->rl_cmdstat = htole32(cmdstat | ctx->rl_flags);
-		i++;
-		if (i == nseg)
-			break;
-		RL_DESC_INC(idx);
 	}
 
-	d->rl_cmdstat |= htole32(RL_TDESC_CMD_EOF);
-	ctx->rl_maxsegs = nseg;
-	ctx->rl_idx = idx;
+	return (ENXIO);
 }
 
 /*
@@ -1071,21 +980,52 @@
 	device_t		dev;
 	struct rl_softc		*sc;
 {
+	bus_size_t		rx_list_size, tx_list_size;
 	int			error;
-	int			nseg;
 	int			i;
 
+	rx_list_size = sc->rl_ldata.rl_rx_desc_cnt * sizeof(struct rl_desc);
+	tx_list_size = sc->rl_ldata.rl_tx_desc_cnt * sizeof(struct rl_desc);
+
+	/*
+	 * Allocate the parent bus DMA tag appropriate for PCI.
+	 * In order to use DAC, RL_CPLUSCMD_PCI_DAC bit of RL_CPLUS_CMD
+	 * register should be set. However some RealTek chips are known
+	 * to be buggy on DAC handling, therefore disable DAC by limiting
+	 * DMA address space to 32bit. PCIe variants of RealTek chips
+	 * may not have the limitation but I took safer path.
+	 */
+	error = bus_dma_tag_create(bus_get_dma_tag(dev), 1, 0,
+	    BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
+	    BUS_SPACE_MAXSIZE_32BIT, 0, BUS_SPACE_MAXSIZE_32BIT, 0,
+	    NULL, NULL, &sc->rl_parent_tag);
+	if (error) {
+		device_printf(dev, "could not allocate parent DMA tag\n");
+		return (error);
+	}
+
 	/*
+	 * Allocate map for TX mbufs.
+	 */
+	error = bus_dma_tag_create(sc->rl_parent_tag, 1, 0,
+	    BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL,
+	    NULL, MCLBYTES * RL_NTXSEGS, RL_NTXSEGS, 4096, 0,
+	    NULL, NULL, &sc->rl_ldata.rl_tx_mtag);
+	if (error) {
+		device_printf(dev, "could not allocate TX DMA tag\n");
+		return (error);
+	}
+
+	/*
 	 * Allocate map for RX mbufs.
 	 */
-	nseg = 32;
-	error = bus_dma_tag_create(sc->rl_parent_tag, ETHER_ALIGN, 0,
-	    BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL,
-	    NULL, MCLBYTES * nseg, nseg, MCLBYTES, BUS_DMA_ALLOCNOW,
-	    NULL, NULL, &sc->rl_ldata.rl_mtag);
+
+	error = bus_dma_tag_create(sc->rl_parent_tag, sizeof(uint64_t), 0,
+	    BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL, NULL,
+	    MCLBYTES, 1, MCLBYTES, 0, NULL, NULL, &sc->rl_ldata.rl_rx_mtag);
 	if (error) {
-		device_printf(dev, "could not allocate dma tag\n");
-		return (ENOMEM);
+		device_printf(dev, "could not allocate RX DMA tag\n");
+		return (error);
 	}
 
 	/*
@@ -1093,36 +1033,44 @@
 	 */
 	error = bus_dma_tag_create(sc->rl_parent_tag, RL_RING_ALIGN,
 	    0, BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL,
-	    NULL, RL_TX_LIST_SZ, 1, RL_TX_LIST_SZ, 0,
+	    NULL, tx_list_size, 1, tx_list_size, 0,
 	    NULL, NULL, &sc->rl_ldata.rl_tx_list_tag);
 	if (error) {
-		device_printf(dev, "could not allocate dma tag\n");
-		return (ENOMEM);
+		device_printf(dev, "could not allocate TX DMA ring tag\n");
+		return (error);
 	}
 
 	/* Allocate DMA'able memory for the TX ring */
 
 	error = bus_dmamem_alloc(sc->rl_ldata.rl_tx_list_tag,
-	    (void **)&sc->rl_ldata.rl_tx_list, BUS_DMA_NOWAIT | BUS_DMA_ZERO,
+	    (void **)&sc->rl_ldata.rl_tx_list,
+	    BUS_DMA_WAITOK | BUS_DMA_COHERENT | BUS_DMA_ZERO,
 	    &sc->rl_ldata.rl_tx_list_map);
-	if (error)
-		return (ENOMEM);
+	if (error) {
+		device_printf(dev, "could not allocate TX DMA ring\n");
+		return (error);
+	}
 
 	/* Load the map for the TX ring. */
 
+	sc->rl_ldata.rl_tx_list_addr = 0;
 	error = bus_dmamap_load(sc->rl_ldata.rl_tx_list_tag,
 	     sc->rl_ldata.rl_tx_list_map, sc->rl_ldata.rl_tx_list,
-	     RL_TX_LIST_SZ, re_dma_map_addr,
+	     tx_list_size, re_dma_map_addr,
 	     &sc->rl_ldata.rl_tx_list_addr, BUS_DMA_NOWAIT);
+	if (error != 0 || sc->rl_ldata.rl_tx_list_addr == 0) {
+		device_printf(dev, "could not load TX DMA ring\n");
+		return (ENOMEM);
+	}
 
 	/* Create DMA maps for TX buffers */
 
-	for (i = 0; i < RL_TX_DESC_CNT; i++) {
-		error = bus_dmamap_create(sc->rl_ldata.rl_mtag, 0,
-			    &sc->rl_ldata.rl_tx_dmamap[i]);
+	for (i = 0; i < sc->rl_ldata.rl_tx_desc_cnt; i++) {
+		error = bus_dmamap_create(sc->rl_ldata.rl_tx_mtag, 0,
+		    &sc->rl_ldata.rl_tx_desc[i].tx_dmamap);
 		if (error) {
-			device_printf(dev, "can't create DMA map for TX\n");
-			return (ENOMEM);
+			device_printf(dev, "could not create DMA map for TX\n");
+			return (error);
 		}
 	}
 
@@ -1131,36 +1079,50 @@
 	 */
 	error = bus_dma_tag_create(sc->rl_parent_tag, RL_RING_ALIGN,
 	    0, BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL,
-	    NULL, RL_RX_LIST_SZ, 1, RL_RX_LIST_SZ, 0,
+	    NULL, rx_list_size, 1, rx_list_size, 0,
 	    NULL, NULL, &sc->rl_ldata.rl_rx_list_tag);
 	if (error) {
-		device_printf(dev, "could not allocate dma tag\n");
-		return (ENOMEM);
+		device_printf(dev, "could not create RX DMA ring tag\n");
+		return (error);
 	}
 
 	/* Allocate DMA'able memory for the RX ring */
 
 	error = bus_dmamem_alloc(sc->rl_ldata.rl_rx_list_tag,
-	    (void **)&sc->rl_ldata.rl_rx_list, BUS_DMA_NOWAIT | BUS_DMA_ZERO,
+	    (void **)&sc->rl_ldata.rl_rx_list,
+	    BUS_DMA_WAITOK | BUS_DMA_COHERENT | BUS_DMA_ZERO,
 	    &sc->rl_ldata.rl_rx_list_map);
-	if (error)
-		return (ENOMEM);
+	if (error) {
+		device_printf(dev, "could not allocate RX DMA ring\n");
+		return (error);
+	}
 
 	/* Load the map for the RX ring. */
 
+	sc->rl_ldata.rl_rx_list_addr = 0;
 	error = bus_dmamap_load(sc->rl_ldata.rl_rx_list_tag,
 	     sc->rl_ldata.rl_rx_list_map, sc->rl_ldata.rl_rx_list,
-	     RL_RX_LIST_SZ, re_dma_map_addr,
+	     rx_list_size, re_dma_map_addr,
 	     &sc->rl_ldata.rl_rx_list_addr, BUS_DMA_NOWAIT);
+	if (error != 0 || sc->rl_ldata.rl_rx_list_addr == 0) {
+		device_printf(dev, "could not load RX DMA ring\n");
+		return (ENOMEM);
+	}
 
 	/* Create DMA maps for RX buffers */
 
-	for (i = 0; i < RL_RX_DESC_CNT; i++) {
-		error = bus_dmamap_create(sc->rl_ldata.rl_mtag, 0,
-			    &sc->rl_ldata.rl_rx_dmamap[i]);
+	error = bus_dmamap_create(sc->rl_ldata.rl_rx_mtag, 0,
+	    &sc->rl_ldata.rl_rx_sparemap);
+	if (error) {
+		device_printf(dev, "could not create spare DMA map for RX\n");
+		return (error);
+	}
+	for (i = 0; i < sc->rl_ldata.rl_rx_desc_cnt; i++) {
+		error = bus_dmamap_create(sc->rl_ldata.rl_rx_mtag, 0,
+		    &sc->rl_ldata.rl_rx_desc[i].rx_dmamap);
 		if (error) {
-			device_printf(dev, "can't create DMA map for RX\n");
-			return (ENOMEM);
+			device_printf(dev, "could not create DMA map for RX\n");
+			return (error);
 		}
 	}
 
@@ -1184,6 +1146,7 @@
 	u_int16_t		re_did = 0;
 	int			error = 0, rid, i;
 	int			msic, reg;
+	uint8_t			cfg;
 
 	sc = device_get_softc(dev);
 	sc->rl_dev = dev;
@@ -1222,6 +1185,12 @@
 				device_printf(dev, "Using %d MSI messages\n",
 				    msic);
 				sc->rl_msi = 1;
+				/* Explicitly set MSI enable bit. */
+				CSR_WRITE_1(sc, RL_EECMD, RL_EE_MODE);
+				cfg = CSR_READ_1(sc, RL_CFG2);
+				cfg |= RL_CFG2_MSI;
+				CSR_WRITE_1(sc, RL_CFG2, cfg);
+				CSR_WRITE_1(sc, RL_EECMD, 0);
 			} else
 				pci_release_msi(dev);
 		}
@@ -1265,6 +1234,11 @@
 		}
 		hw_rev++;
 	}
+	if (hw_rev->rl_desc == NULL) {
+		device_printf(dev, "Unknown H/W revision: %08x\n", hwrev);
+		error = ENXIO;
+		goto fail;
+	}
 
 	sc->rl_eewidth = RL_9356_ADDR_LEN;
 	re_read_eeprom(sc, (caddr_t)&re_did, 0, 1);
@@ -1280,28 +1254,25 @@
 	bcopy(as, eaddr, sizeof(eaddr));
 
 	if (sc->rl_type == RL_8169) {
-		/* Set RX length mask */
+		/* Set RX length mask and number of descriptors. */
 		sc->rl_rxlenmask = RL_RDESC_STAT_GFRAGLEN;
 		sc->rl_txstart = RL_GTXSTART;
+		sc->rl_ldata.rl_tx_desc_cnt = RL_8169_TX_DESC_CNT;
+		sc->rl_ldata.rl_rx_desc_cnt = RL_8169_RX_DESC_CNT;
 	} else {
-		/* Set RX length mask */
+		/* Set RX length mask and number of descriptors. */
 		sc->rl_rxlenmask = RL_RDESC_STAT_FRAGLEN;
 		sc->rl_txstart = RL_TXSTART;
+		sc->rl_ldata.rl_tx_desc_cnt = RL_8139_TX_DESC_CNT;
+		sc->rl_ldata.rl_rx_desc_cnt = RL_8139_RX_DESC_CNT;
 	}
-
-	/*
-	 * Allocate the parent bus DMA tag appropriate for PCI.
-	 */
-#define RL_NSEG_NEW 32
-	error = bus_dma_tag_create(bus_get_dma_tag(dev), 1, 0,
-	    BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
-	    MAXBSIZE, RL_NSEG_NEW, BUS_SPACE_MAXSIZE_32BIT, 0,
-	    NULL, NULL, &sc->rl_parent_tag);
-	if (error)
+	if (hw_rev->rl_desc == NULL) {
+		device_printf(dev, "Unsupported revision : 0x%08x\n", hwrev);
+		error = ENXIO;
 		goto fail;
+	}
 
 	error = re_allocmem(dev, sc);
-
 	if (error)
 		goto fail;
 
@@ -1348,8 +1319,8 @@
 	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
 	ifp->if_ioctl = re_ioctl;
 	ifp->if_start = re_start;
-	ifp->if_hwassist = RE_CSUM_FEATURES;
-	ifp->if_capabilities = IFCAP_HWCSUM;
+	ifp->if_hwassist = RE_CSUM_FEATURES | CSUM_TSO;
+	ifp->if_capabilities = IFCAP_HWCSUM | IFCAP_TSO4;
 	ifp->if_capenable = ifp->if_capabilities;
 	ifp->if_init = re_init;
 	IFQ_SET_MAXLEN(&ifp->if_snd, RL_IFQ_MAXLEN);
@@ -1368,6 +1339,9 @@
 	ifp->if_capabilities |= IFCAP_VLAN_MTU | IFCAP_VLAN_HWTAGGING;
 	if (ifp->if_capabilities & IFCAP_HWCSUM)
 		ifp->if_capabilities |= IFCAP_VLAN_HWCSUM;
+	/* Enable WOL if PM is supported. */
+	if (pci_find_extcap(sc->rl_dev, PCIY_PMG, &reg) == 0)
+		ifp->if_capabilities |= IFCAP_WOL;
 	ifp->if_capenable = ifp->if_capabilities;
 #ifdef DEVICE_POLLING
 	ifp->if_capabilities |= IFCAP_POLLING;
@@ -1534,14 +1508,20 @@
 
 	/* Destroy all the RX and TX buffer maps */
 
-	if (sc->rl_ldata.rl_mtag) {
-		for (i = 0; i < RL_TX_DESC_CNT; i++)
-			bus_dmamap_destroy(sc->rl_ldata.rl_mtag,
-			    sc->rl_ldata.rl_tx_dmamap[i]);
-		for (i = 0; i < RL_RX_DESC_CNT; i++)
-			bus_dmamap_destroy(sc->rl_ldata.rl_mtag,
-			    sc->rl_ldata.rl_rx_dmamap[i]);
-		bus_dma_tag_destroy(sc->rl_ldata.rl_mtag);
+	if (sc->rl_ldata.rl_tx_mtag) {
+		for (i = 0; i < sc->rl_ldata.rl_tx_desc_cnt; i++)
+			bus_dmamap_destroy(sc->rl_ldata.rl_tx_mtag,
+			    sc->rl_ldata.rl_tx_desc[i].tx_dmamap);
+		bus_dma_tag_destroy(sc->rl_ldata.rl_tx_mtag);
+	}
+	if (sc->rl_ldata.rl_rx_mtag) {
+		for (i = 0; i < sc->rl_ldata.rl_rx_desc_cnt; i++)
+			bus_dmamap_destroy(sc->rl_ldata.rl_rx_mtag,
+			    sc->rl_ldata.rl_rx_desc[i].rx_dmamap);
+		if (sc->rl_ldata.rl_rx_sparemap)
+			bus_dmamap_destroy(sc->rl_ldata.rl_rx_mtag,
+			    sc->rl_ldata.rl_rx_sparemap);
+		bus_dma_tag_destroy(sc->rl_ldata.rl_rx_mtag);
 	}
 
 	/* Unload and free the stats buffer and map */
@@ -1563,23 +1543,40 @@
 	return (0);
 }
 
+static __inline void
+re_discard_rxbuf(sc, idx)
+	struct rl_softc		*sc;
+	int			idx;
+{
+	struct rl_desc		*desc;
+	struct rl_rxdesc	*rxd;
+	uint32_t		cmdstat;
+
+	rxd = &sc->rl_ldata.rl_rx_desc[idx];
+	desc = &sc->rl_ldata.rl_rx_list[idx];
+	desc->rl_vlanctl = 0;
+	cmdstat = rxd->rx_size;
+	if (idx == sc->rl_ldata.rl_rx_desc_cnt - 1)
+		cmdstat |= RL_RDESC_CMD_EOR;
+	desc->rl_cmdstat = htole32(cmdstat | RL_RDESC_CMD_OWN);
+}
+
 static int
-re_newbuf(sc, idx, m)
+re_newbuf(sc, idx)
 	struct rl_softc		*sc;
 	int			idx;
+{
 	struct mbuf		*m;

>>> TRUNCATED FOR MAIL (1000 lines) <<<


More information about the p4-projects mailing list