Module Name:    src
Committed By:   tsutsui
Date:           Wed Mar  3 13:39:58 UTC 2010

Modified Files:
        src/sys/arch/x68k/dev: if_ne_intio.c if_ne_neptune.c
        src/sys/conf: files
        src/sys/dev/ic: ne2000.c ne2000var.h
        src/sys/dev/isa: if_ne_isa.c
        src/sys/dev/isapnp: if_ne_isapnp.c

Log Message:
Put several fixes to ne(4) driver for better 8 bit mode support,
especially on RTL8019AS which is also used for non-ISA local bus of
embedded controllers and some m68k machines like atari and x68k.

 * move RTL8019 probe and attach code from each bus attachment
   to MI ne2000_detect() and ne2000_attach()
 * change a method for backend and attachment to specify 8 bit mode
   to use a new sc->sc_quirk member, instead of sc->sc_dmawidth
 * handle more NE2000 8 bit mode specific settings, including
   bus_space(9) access width and available size of buffer memory
 * add a function to detect NE2000 8 bit mode
   (disabled by default, but enalbed by options NE2000_DETECT_8BIT
    to avoid possible regression on various ISA clones)
 * fix ipkdb attachment accordingly (untested)

Tested on two NE2000 ISA variants (RTL8019AS and another clone named UL0001)
in both 8 bit and 16 bit mode on i386. "Looks good" from non...@.

See my post on tech-kern for details:
http://mail-index.NetBSD.org/tech-kern/2010/02/26/msg007423.html


To generate a diff of this commit:
cvs rdiff -u -r1.15 -r1.16 src/sys/arch/x68k/dev/if_ne_intio.c
cvs rdiff -u -r1.19 -r1.20 src/sys/arch/x68k/dev/if_ne_neptune.c
cvs rdiff -u -r1.979 -r1.980 src/sys/conf/files
cvs rdiff -u -r1.67 -r1.68 src/sys/dev/ic/ne2000.c
cvs rdiff -u -r1.24 -r1.25 src/sys/dev/ic/ne2000var.h
cvs rdiff -u -r1.26 -r1.27 src/sys/dev/isa/if_ne_isa.c
cvs rdiff -u -r1.26 -r1.27 src/sys/dev/isapnp/if_ne_isapnp.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/x68k/dev/if_ne_intio.c
diff -u src/sys/arch/x68k/dev/if_ne_intio.c:1.15 src/sys/arch/x68k/dev/if_ne_intio.c:1.16
--- src/sys/arch/x68k/dev/if_ne_intio.c:1.15	Tue Jan 19 22:06:23 2010
+++ src/sys/arch/x68k/dev/if_ne_intio.c	Wed Mar  3 13:39:57 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_ne_intio.c,v 1.15 2010/01/19 22:06:23 pooka Exp $	*/
+/*	$NetBSD: if_ne_intio.c,v 1.16 2010/03/03 13:39:57 tsutsui Exp $	*/
 
 /*
  * Copyright (c) 2001 Tetsuya Isaki. All rights reserved.
@@ -32,7 +32,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_ne_intio.c,v 1.15 2010/01/19 22:06:23 pooka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_ne_intio.c,v 1.16 2010/03/03 13:39:57 tsutsui Exp $");
 
 #include "opt_inet.h"
 #include "opt_ns.h"
@@ -74,8 +74,6 @@
 #include <dev/ic/dp8390var.h>
 #include <dev/ic/ne2000reg.h>
 #include <dev/ic/ne2000var.h>
-#include <dev/ic/rtl80x9reg.h>
-#include <dev/ic/rtl80x9var.h>
 
 #include <arch/x68k/dev/intiovar.h>
 
@@ -187,21 +185,10 @@
 
 	case NE2000_TYPE_NE2000:
 		typestr = "NE2000";
-		/*
-		 * Check for a Realtek 8019.
-		 */
-		bus_space_write_1(iot, ioh, ED_P0_CR,
-			ED_CR_PAGE_0 | ED_CR_STP);
-		if (bus_space_read_1(iot, ioh, NERTL_RTL0_8019ID0) ==
-		      RTL0_8019ID0 &&
-		      bus_space_read_1(iot, ioh, NERTL_RTL0_8019ID1) ==
-		      RTL0_8019ID1) {
-			typestr = "NE2000 (RTL8019)";
-			dsc->sc_mediachange = rtl80x9_mediachange;
-			dsc->sc_mediastatus = rtl80x9_mediastatus;
-			dsc->init_card      = rtl80x9_init_card;
-			dsc->sc_media_init  = rtl80x9_media_init;
-		}
+		break;
+
+	case NE2000_TYPE_RTL8019:
+		typestr = "NE2000 (RTL8019)";
 		break;
 
 	default:

Index: src/sys/arch/x68k/dev/if_ne_neptune.c
diff -u src/sys/arch/x68k/dev/if_ne_neptune.c:1.19 src/sys/arch/x68k/dev/if_ne_neptune.c:1.20
--- src/sys/arch/x68k/dev/if_ne_neptune.c:1.19	Tue Jan 19 22:06:23 2010
+++ src/sys/arch/x68k/dev/if_ne_neptune.c	Wed Mar  3 13:39:57 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_ne_neptune.c,v 1.19 2010/01/19 22:06:23 pooka Exp $	*/
+/*	$NetBSD: if_ne_neptune.c,v 1.20 2010/03/03 13:39:57 tsutsui Exp $	*/
 
 /*-
  * Copyright (c) 1997, 1998 The NetBSD Foundation, Inc.
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_ne_neptune.c,v 1.19 2010/01/19 22:06:23 pooka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_ne_neptune.c,v 1.20 2010/03/03 13:39:57 tsutsui Exp $");
 
 #include "opt_inet.h"
 #include "opt_ns.h"
@@ -72,9 +72,6 @@
 #include <dev/ic/ne2000reg.h>
 #include <dev/ic/ne2000var.h>
 
-#include <dev/ic/rtl80x9reg.h>
-#include <dev/ic/rtl80x9var.h>
-
 #include <arch/x68k/dev/neptunevar.h>
 
 static int ne_neptune_match(device_t, cfdata_t, void *);
@@ -165,21 +162,10 @@
 
 	case NE2000_TYPE_NE2000:
 		typestr = "NE2000";
-		/*
-		 * Check for a Realtek 8019.
-		 */
-		bus_space_write_1(nict, nich, ED_P0_CR,
-		    ED_CR_PAGE_0 | ED_CR_STP);
-		if (bus_space_read_1(nict, nich, NERTL_RTL0_8019ID0) ==
-								RTL0_8019ID0 &&
-		    bus_space_read_1(nict, nich, NERTL_RTL0_8019ID1) ==
-								RTL0_8019ID1) {
-			typestr = "NE2000 (RTL8019)";
-			dsc->sc_mediachange = rtl80x9_mediachange;
-			dsc->sc_mediastatus = rtl80x9_mediastatus;
-			dsc->init_card = rtl80x9_init_card;
-			dsc->sc_media_init = rtl80x9_media_init;
-		}
+		break;
+
+	case NE2000_TYPE_RTL8019:
+		typestr = "NE2000 (RTL8019)";
 		break;
 
 	default:

Index: src/sys/conf/files
diff -u src/sys/conf/files:1.979 src/sys/conf/files:1.980
--- src/sys/conf/files:1.979	Tue Mar  2 13:27:27 2010
+++ src/sys/conf/files	Wed Mar  3 13:39:57 2010
@@ -1,4 +1,4 @@
-#	$NetBSD: files,v 1.979 2010/03/02 13:27:27 uebayasi Exp $
+#	$NetBSD: files,v 1.980 2010/03/03 13:39:57 tsutsui Exp $
 #	@(#)files.newconf	7.5 (Berkeley) 5/10/93
 
 version 	20090313
@@ -901,7 +901,7 @@
 # Realtek 8019/8029 NE2000-compatible network interface subroutines
 #
 define	rtl80x9
-file	dev/ic/rtl80x9.c		rtl80x9
+file	dev/ic/rtl80x9.c		rtl80x9			needs-flag
 
 # Realtek 8129/8139 Ethernet controllers
 #

Index: src/sys/dev/ic/ne2000.c
diff -u src/sys/dev/ic/ne2000.c:1.67 src/sys/dev/ic/ne2000.c:1.68
--- src/sys/dev/ic/ne2000.c:1.67	Wed Feb 24 22:37:58 2010
+++ src/sys/dev/ic/ne2000.c	Wed Mar  3 13:39:57 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: ne2000.c,v 1.67 2010/02/24 22:37:58 dyoung Exp $	*/
+/*	$NetBSD: ne2000.c,v 1.68 2010/03/03 13:39:57 tsutsui Exp $	*/
 
 /*-
  * Copyright (c) 1997, 1998 The NetBSD Foundation, Inc.
@@ -48,10 +48,12 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ne2000.c,v 1.67 2010/02/24 22:37:58 dyoung Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ne2000.c,v 1.68 2010/03/03 13:39:57 tsutsui Exp $");
 
 #include "opt_ipkdb.h"
 
+#include "rtl80x9.h"
+
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/device.h>
@@ -85,6 +87,9 @@
 #include <dev/ic/ne2000reg.h>
 #include <dev/ic/ne2000var.h>
 
+#include <dev/ic/rtl80x9reg.h>
+#include <dev/ic/rtl80x9var.h>
+
 #include <dev/ic/ax88190reg.h>
 
 int	ne2000_write_mbuf(struct dp8390_softc *, struct mbuf *, int);
@@ -98,6 +103,11 @@
 void	ne2000_readmem(bus_space_tag_t, bus_space_handle_t,
 	    bus_space_tag_t, bus_space_handle_t, int, u_int8_t *, size_t, int);
 
+#ifdef NE2000_DETECT_8BIT
+static bool	ne2000_detect_8bit(bus_space_tag_t, bus_space_handle_t,
+		    bus_space_tag_t, bus_space_handle_t);
+#endif
+
 #define	ASIC_BARRIER(asict, asich) \
 	bus_space_barrier((asict), (asich), 0, 0x10, \
 	    BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE)
@@ -111,7 +121,7 @@
 	bus_space_tag_t asict = nsc->sc_asict;
 	bus_space_handle_t asich = nsc->sc_asich;
 	u_int8_t romdata[16];
-	int memsize, i, useword, dmawidth;
+	int memstart, memsize, i, useword;
 
 	/*
 	 * Detect it again unless caller specified it; this gives us
@@ -130,30 +140,46 @@
 		aprint_error_dev(dsc->sc_dev, "where did the card go?\n");
 		return (1);
 	case NE2000_TYPE_NE1000:
+		memstart = 8192;
 		memsize = 8192;
 		useword = 0;
-		dmawidth = NE2000_DMAWIDTH_8BIT;
 		break;
 	case NE2000_TYPE_NE2000:
 	case NE2000_TYPE_AX88190:		/* XXX really? */
 	case NE2000_TYPE_AX88790:
-		memsize = 8192 * 2;
+#if NRTL80X9 > 0
+	case NE2000_TYPE_RTL8019:
+#endif
+		memstart = 16384;
+		memsize = 16384;
 		useword = 1;
-		dmawidth = NE2000_DMAWIDTH_16BIT;
+		if (
+#ifdef NE2000_DETECT_8BIT
+		    ne2000_detect_8bit(nict, nich, asict, asich) ||
+#endif
+		    (nsc->sc_quirk & NE2000_QUIRK_8BIT) != 0) {
+			/* in 8 bit mode, only 8KB memory can be used */
+			memsize = 8192;
+			useword = 0;
+		}
 		break;
 	case NE2000_TYPE_DL10019:
 	case NE2000_TYPE_DL10022:
+		memstart = 8192 * 3;
 		memsize = 8192 * 3;
 		useword = 1;
-		dmawidth = NE2000_DMAWIDTH_16BIT;
 		break;
 	}
 
 	nsc->sc_useword = useword;
-	if (nsc->sc_dmawidth == NE2000_DMAWIDTH_UNKNOWN)
-		nsc->sc_dmawidth = dmawidth;
-	else
-		dmawidth = nsc->sc_dmawidth;
+#if NRTL80X9 > 0
+	if (nsc->sc_type == NE2000_TYPE_RTL8019) {
+		dsc->init_card = rtl80x9_init_card;
+		dsc->sc_media_init = rtl80x9_media_init;
+		dsc->sc_mediachange = rtl80x9_mediachange;
+		dsc->sc_mediastatus = rtl80x9_mediastatus;
+	}
+#endif
 
 	dsc->cr_proto = ED_CR_RD2;
 	if (nsc->sc_type == NE2000_TYPE_AX88190 ||
@@ -171,8 +197,7 @@
 	 *
 	 * NE1000 gets byte-wide DMA, NE2000 gets word-wide DMA.
 	 */
-	dsc->dcr_reg = ED_DCR_FT1 | ED_DCR_LS |
-	    ((dmawidth == NE2000_DMAWIDTH_16BIT) ? ED_DCR_WTS : 0);
+	dsc->dcr_reg = ED_DCR_FT1 | ED_DCR_LS | (useword ? ED_DCR_WTS : 0);
 
 	dsc->test_mem = ne2000_test_mem;
 	dsc->ring_copy = ne2000_ring_copy;
@@ -186,16 +211,14 @@
 	/*
 	 * NIC memory doens't start at zero on an NE board.
 	 * The start address is tied to the bus width.
-	 * (It happens to be computed the same way as mem size.)
 	 */
-	dsc->mem_start = memsize;
-
 #ifdef GWETHER
 	{
-		int x, mstart = 0;
+		int x;
 		int8_t pbuf0[ED_PAGE_SIZE], pbuf[ED_PAGE_SIZE],
 		    tbuf[ED_PAGE_SIZE];
 
+		memstart = 0;
 		for (i = 0; i < ED_PAGE_SIZE; i++)
 			pbuf0[i] = 0;
 
@@ -215,14 +238,14 @@
 				    x << ED_PAGE_SHIFT, tbuf, ED_PAGE_SIZE,
 				    useword);
 				if (memcmp(pbuf, tbuf, ED_PAGE_SIZE) == 0) {
-					mstart = x << ED_PAGE_SHIFT;
+					memstart = x << ED_PAGE_SHIFT;
 					memsize = ED_PAGE_SIZE;
 					break;
 				}
 			}
 		}
 
-		if (mstart == 0) {
+		if (memstart == 0) {
 			aprint_error_dev(&dsc->sc_dev, "cannot find start of RAM\n");
 			return (1);
 		}
@@ -251,11 +274,10 @@
 		}
 
 		printf("%s: RAM start 0x%x, size %d\n",
-		    device_xname(&dsc->sc_dev), mstart, memsize);
-
-		dsc->mem_start = mstart;
+		    device_xname(&dsc->sc_dev), memstart, memsize);
 	}
 #endif /* GWETHER */
+	dsc->mem_start = memstart;
 
 	dsc->mem_size = memsize;
 
@@ -270,17 +292,19 @@
 			NIC_BARRIER(nict, nich);
 			/* Select word transfer. */
 			bus_space_write_1(nict, nich, ED_P0_DCR,
-			    ((dmawidth == NE2000_DMAWIDTH_16BIT) ? ED_DCR_WTS : 0));
+			    useword ? ED_DCR_WTS : 0);
 			NIC_BARRIER(nict, nich);
 			ne2000_readmem(nict, nich, asict, asich,
 			    AX88190_NODEID_OFFSET, dsc->sc_enaddr,
 			    ETHER_ADDR_LEN, useword);
 		} else {
+			bool ne1000 = (nsc->sc_type == NE2000_TYPE_NE1000);
+
 			ne2000_readmem(nict, nich, asict, asich, 0, romdata,
 			    sizeof(romdata), useword);
 			for (i = 0; i < ETHER_ADDR_LEN; i++)
 				dsc->sc_enaddr[i] =
-				    romdata[i * (useword ? 2 : 1)];
+				    romdata[i * (ne1000 ? 1 : 2)];
 		}
 	} else
 		memcpy(dsc->sc_enaddr, myea, sizeof(dsc->sc_enaddr));
@@ -310,9 +334,8 @@
 	static u_int8_t test_pattern[32] = "THIS is A memory TEST pattern";
 	u_int8_t test_buffer[32], tmp;
 	int i, rv = NE2000_TYPE_UNKNOWN;
-	int dmawidth = NE2000_DMAWIDTH_16BIT;
+	int useword;
 
- restart:
 	/* Reset the board. */
 #ifdef GWETHER
 	bus_space_write_1(asict, asich, NE2000_ASIC_RESET, 0);
@@ -426,48 +449,96 @@
 	ne2000_readmem(nict, nich, asict, asich, 8192, test_buffer,
 	    sizeof(test_buffer), 0);
 
-	if (memcmp(test_pattern, test_buffer, sizeof(test_pattern))) {
-		/* not an NE1000 - try NE2000 */
-		bus_space_write_1(nict, nich, ED_P0_DCR, ED_DCR_FT1 | ED_DCR_LS
-		    | ((dmawidth == NE2000_DMAWIDTH_16BIT) ? ED_DCR_WTS : 0));
-		bus_space_write_1(nict, nich, ED_P0_PSTART,
-		    16384 >> ED_PAGE_SHIFT);
-		bus_space_write_1(nict, nich, ED_P0_PSTOP,
-		    32768 >> ED_PAGE_SHIFT);
-
-		/*
-		 * Write the test pattern in word mode.  If this also fails,
-		 * then we don't know what this board is.
-		 */
-		ne2000_writemem(nict, nich, asict, asich, test_pattern, 16384,
-		    sizeof(test_pattern), 1, 0);
-		ne2000_readmem(nict, nich, asict, asich, 16384, test_buffer,
-		    sizeof(test_buffer), 1);
-
-		if (memcmp(test_pattern, test_buffer, sizeof(test_pattern))) {
-			if (dmawidth == NE2000_DMAWIDTH_16BIT) {
-				/* try 8bit dma */
-				dmawidth = NE2000_DMAWIDTH_8BIT;
-				goto restart;
-			}
-			goto out;	/* not an NE2000 either */
-		}
-
-		rv = NE2000_TYPE_NE2000;
-	} else {
+	if (memcmp(test_pattern, test_buffer, sizeof(test_pattern)) == 0) {
 		/* We're an NE1000. */
 		rv = NE2000_TYPE_NE1000;
-		dmawidth = NE2000_DMAWIDTH_8BIT;
+		goto out;
+	}
+
+	/* not an NE1000 - try NE2000 */
+
+	/* try 16 bit mode first */
+	useword = 1;
+
+#ifdef NE2000_DETECT_8BIT
+	/*
+	 * Check bus type in EEPROM first because some NE2000 compatible wedges
+	 * on 16 bit DMA access if the chip is configured in 8 bit mode.
+	 */
+	if (ne2000_detect_8bit(nict, nich, asict, asich))
+		useword = 0;
+#endif
+ again:
+	bus_space_write_1(nict, nich, ED_P0_DCR, ED_DCR_FT1 | ED_DCR_LS |
+	    (useword ? ED_DCR_WTS : 0));
+	bus_space_write_1(nict, nich, ED_P0_PSTART, 16384 >> ED_PAGE_SHIFT);
+	bus_space_write_1(nict, nich, ED_P0_PSTOP,
+	    (16384 + (useword ? 16384 : 8192)) >> ED_PAGE_SHIFT);
+
+	/*
+	 * Write the test pattern in word mode.  If this also fails,
+	 * then we don't know what this board is.
+	 */
+	ne2000_writemem(nict, nich, asict, asich, test_pattern, 16384,
+	    sizeof(test_pattern), useword, 0);
+	ne2000_readmem(nict, nich, asict, asich, 16384, test_buffer,
+	    sizeof(test_buffer), useword);
+
+	if (memcmp(test_pattern, test_buffer, sizeof(test_pattern)) != 0) {
+		if (useword == 1) {
+			/* try 8 bit mode */
+			useword = 0;
+			goto again;
+		}
+		return NE2000_TYPE_UNKNOWN;	/* not an NE2000 either */
 	}
 
+	rv = NE2000_TYPE_NE2000;
+
+#if NRTL80X9 > 0
+	/* Check for a Realtek RTL8019. */
+	if (bus_space_read_1(nict, nich, NERTL_RTL0_8019ID0) == RTL0_8019ID0 &&
+	    bus_space_read_1(nict, nich, NERTL_RTL0_8019ID1) == RTL0_8019ID1)
+		rv = NE2000_TYPE_RTL8019;
+#endif
+
+ out:
 	/* Clear any pending interrupts that might have occurred above. */
 	NIC_BARRIER(nict, nich);
 	bus_space_write_1(nict, nich, ED_P0_ISR, 0xff);
 
- out:
 	return (rv);
 }
 
+#ifdef NE2000_DETECT_8BIT
+static bool
+ne2000_detect_8bit(bus_space_tag_t nict, bus_space_handle_t nich,
+    bus_space_tag_t asict, bus_space_handle_t asich)
+{
+	bool is8bit;
+	uint8_t romdata[32];
+
+	is8bit = false;
+
+	/* Set DCR for 8 bit DMA. */
+	bus_space_write_1(nict, nich, ED_P0_DCR, ED_DCR_FT1 | ED_DCR_LS);
+	/* Read PROM area. */
+	ne2000_readmem(nict, nich, asict, asich, 0, romdata,
+	    sizeof(romdata), 0);
+	if (romdata[28] == 'B' && romdata[30] == 'B') {
+		/* 'B' (0x42) in 8 bit mode, 'W' (0x57) in 16 bit mode */
+		is8bit = true;
+	} 
+	if (!is8bit) {
+		/* not in 8 bit mode; put back DCR setting for 16 bit DMA */
+		bus_space_write_1(nict, nich, ED_P0_DCR,
+		    ED_DCR_FT1 | ED_DCR_LS | ED_DCR_WTS);
+	}
+
+	return is8bit;
+}
+#endif
+
 /*
  * Write an mbuf chain to the destination NIC memory address using programmed
  * I/O.
@@ -521,8 +592,8 @@
 	 * so that case requires some extra code to patch over odd-length
 	 * mbufs.
 	 */
-	if (nsc->sc_type == NE2000_TYPE_NE1000) {
-		/* NE1000s are easy. */
+	if (nsc->sc_useword == 0) {
+		/* byte ops are easy. */
 		for (; m != 0; m = m->m_next) {
 			if (m->m_len) {
 				bus_space_write_multi_1(asict, asich,
@@ -536,7 +607,7 @@
 				    NE2000_ASIC_DATA, 0);
 		}
 	} else {
-		/* NE2000s are a bit trickier. */
+		/* word ops are a bit trickier. */
 		u_int8_t *data, savebyte[2];
 		int l, leftover;
 #ifdef DIAGNOSTIC
@@ -814,7 +885,9 @@
 	struct dp8390_softc *dp = &np->sc_dp8390;
 	bus_space_tag_t nict = dp->sc_regt;
 	bus_space_handle_t nich = dp->sc_regh;
-	int i, useword, dmawidth;
+	bus_space_tag_t asict = np->sc_asict;
+	bus_space_handle_t asich = np->sc_asich;
+	int i, useword;
 
 #ifdef GWETHER
 	/* Not supported (yet?) */
@@ -822,54 +895,80 @@
 #endif
 
 	if (np->sc_type == NE2000_TYPE_UNKNOWN)
-		np->sc_type = ne2000_detect(nict, nich,
-			np->sc_asict, np->sc_asich);
+		np->sc_type = ne2000_detect(nict, nich, asict, asich);
 	if (np->sc_type == NE2000_TYPE_UNKNOWN)
 		return -1;
 
-	useword = np->sc_useword;
-	dmawidth = np->sc_dmawidth;
-
-	dp->cr_proto = ED_CR_RD2;
-	dp->dcr_reg = ED_DCR_FT1 | ED_DCR_LS |
-	    ((dmawidth == NE2000_DMAWIDTH_16BIT) ? ED_DCR_WTS : 0);
-	dp->rcr_proto = 0;
-
-	dp->test_mem = ne2000_test_mem;
-	dp->ring_copy = ne2000_ring_copy;
-	dp->write_mbuf = ne2000_write_mbuf;
-	dp->read_hdr = ne2000_read_hdr;
-
-	for (i = 0; i < 16; i++)
-		dp->sc_reg_map[i] = i;
-
 	switch (np->sc_type) {
 	case NE2000_TYPE_NE1000:
-		dp->mem_start = dp->mem_size = 8192;
+		dp->mem_start = 8192;
+		dp->mem_size = 8192;
+		useword = 0;
 		kip->name = "ne1000";
 		break;
 	case NE2000_TYPE_NE2000:
-		dp->mem_start = dp->mem_size = 8192 * 2;
-		kip->name = "ne2000";
+	case NE2000_TYPE_AX88190:
+	case NE2000_TYPE_AX88790:
+#if NRTL80X9 > 0
+	case NE2000_TYPE_RTL8019:
+#endif
+		dp->mem_start = 16384;
+		dp->mem_size = 16384;
+		useword = 1;
+		if (
+#ifdef NE2000_DETECT_8BIT
+		    ne2000_detect_8bit(nict, nich, asict, asich) ||
+#endif
+		    (np->sc_quirk & NE2000_QUIRK_8BIT) != 0) {
+			/* in 8 bit mode, only 8KB memory can be used */
+			dp->mem_size = 8192;
+			useword = 0;
+		}
+		kip->name =
+		    (np->sc_type == NE2000_TYPE_AX88190 ||
+		     np->sc_type == NE2000_TYPE_AX88790) ?
+		    "ax88190" : "ne2000";
 		break;
 	case NE2000_TYPE_DL10019:
 	case NE2000_TYPE_DL10022:
-		dp->mem_start = dp->mem_size = 8192 * 3;
+		dp->mem_start = 8192 * 3;
+		dp->mem_size = 8192 * 3;
+		useword = 1;
 		kip->name = (np->sc_type == NE2000_TYPE_DL10019) ?
 		    "dl10022" : "dl10019";
 		break;
-	case NE2000_TYPE_AX88190:
-	case NE2000_TYPE_AX88790:
-		dp->rcr_proto = ED_RCR_INTT;
-		dp->sc_flags |= DP8390_DO_AX88190_WORKAROUND;
-		dp->mem_start = dp->mem_size = 8192 * 2;
-		kip->name = "ax88190";
-		break;
 	default:
 		return -1;
 		break;
 	}
 
+	np->sc_useword = useword;
+#if NRTL80X9 > 0
+	if (np->sc_type == NE2000_TYPE_RTL8019) {
+		dp->init_card = rtl80x9_init_card;
+		dp->sc_media_init = rtl80x9_media_init;
+		dp->sc_mediachange = rtl80x9_mediachange;
+		dp->sc_mediastatus = rtl80x9_mediastatus;
+	}
+#endif
+
+	dp->cr_proto = ED_CR_RD2;
+	if (np->sc_type == NE2000_TYPE_AX88190 ||
+	    np->sc_type == NE2000_TYPE_AX88790) {
+		dp->rcr_proto = ED_RCR_INTT;
+		dp->sc_flags |= DP8390_DO_AX88190_WORKAROUND;
+	} else
+		dp->rcr_proto = 0;
+	dp->dcr_reg = ED_DCR_FT1 | ED_DCR_LS | (useword ? ED_DCR_WTS : 0);
+
+	dp->test_mem = ne2000_test_mem;
+	dp->ring_copy = ne2000_ring_copy;
+	dp->write_mbuf = ne2000_write_mbuf;
+	dp->read_hdr = ne2000_read_hdr;
+
+	for (i = 0; i < 16; i++)
+		dp->sc_reg_map[i] = i;
+
 	if (dp8390_ipkdb_attach(kip))
 		return -1;
 
@@ -889,15 +988,18 @@
 			NIC_BARRIER(nict, nich);
 			/* Select word transfer */
 			bus_space_write_1(nict, nich, ED_P0_DCR,
-			    ((dmawidth == NE2000_DMAWIDTH_16BIT) ? ED_DCR_WTS : 0));
-			ne2000_readmem(nict, nich, np->sc_asict, np->sc_asich,
+			    useword ? ED_DCR_WTS : 0);
+			ne2000_readmem(nict, nich, asict, asich,
 				AX88190_NODEID_OFFSET, kip->myenetaddr,
 				ETHER_ADDR_LEN, useword);
 		} else {
-			ne2000_readmem(nict, nich, np->sc_asict, np->sc_asich,
+			bool ne1000 = (np->sc_type == NE2000_TYPE_NE1000);
+
+			ne2000_readmem(nict, nich, asict, asich,
 				0, romdata, sizeof romdata, useword);
 			for (i = 0; i < ETHER_ADDR_LEN; i++)
-				kip->myenetaddr[i] = romdata[i << useword];
+				kip->myenetaddr[i] =
+				    romdata[i * (ne1000 ? 1 : 2)];
 		}
 		kip->flags |= IPKDB_MYHW;
 

Index: src/sys/dev/ic/ne2000var.h
diff -u src/sys/dev/ic/ne2000var.h:1.24 src/sys/dev/ic/ne2000var.h:1.25
--- src/sys/dev/ic/ne2000var.h:1.24	Wed Feb 24 22:37:58 2010
+++ src/sys/dev/ic/ne2000var.h	Wed Mar  3 13:39:57 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: ne2000var.h,v 1.24 2010/02/24 22:37:58 dyoung Exp $	*/
+/*	$NetBSD: ne2000var.h,v 1.25 2010/03/03 13:39:57 tsutsui Exp $	*/
 
 /*-
  * Copyright (c) 1997, 1998 The NetBSD Foundation, Inc.
@@ -46,14 +46,12 @@
 		NE2000_TYPE_DL10019,
 		NE2000_TYPE_DL10022,
 		NE2000_TYPE_AX88190,
-		NE2000_TYPE_AX88790
+		NE2000_TYPE_AX88790,
+		NE2000_TYPE_RTL8019
 	} sc_type;
 	int sc_useword;
-	enum {
-		NE2000_DMAWIDTH_UNKNOWN = 0,
-		NE2000_DMAWIDTH_16BIT,
-		NE2000_DMAWIDTH_8BIT,
-	} sc_dmawidth;
+	u_int sc_quirk;			/* quirks passed from attachments */
+#define	NE2000_QUIRK_8BIT	0x0001	/* force 8bit mode even on NE2000 */
 };
 
 int	ne2000_attach(struct ne2000_softc *, u_int8_t *);

Index: src/sys/dev/isa/if_ne_isa.c
diff -u src/sys/dev/isa/if_ne_isa.c:1.26 src/sys/dev/isa/if_ne_isa.c:1.27
--- src/sys/dev/isa/if_ne_isa.c:1.26	Mon Apr 28 20:23:52 2008
+++ src/sys/dev/isa/if_ne_isa.c	Wed Mar  3 13:39:57 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_ne_isa.c,v 1.26 2008/04/28 20:23:52 martin Exp $	*/
+/*	$NetBSD: if_ne_isa.c,v 1.27 2010/03/03 13:39:57 tsutsui Exp $	*/
 
 /*-
  * Copyright (c) 1997, 1998 The NetBSD Foundation, Inc.
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_ne_isa.c,v 1.26 2008/04/28 20:23:52 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_ne_isa.c,v 1.27 2010/03/03 13:39:57 tsutsui Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -57,9 +57,6 @@
 #include <dev/ic/ne2000reg.h>
 #include <dev/ic/ne2000var.h>
 
-#include <dev/ic/rtl80x9reg.h>
-#include <dev/ic/rtl80x9var.h>
-
 #include <dev/isa/isavar.h>
 
 int	ne_isa_match(device_t, cfdata_t, void *);
@@ -178,21 +175,10 @@
 
 	case NE2000_TYPE_NE2000:
 		typestr = "NE2000";
-		/*
-		 * Check for a Realtek 8019.
-		 */
-		bus_space_write_1(nict, nich, ED_P0_CR,
-		    ED_CR_PAGE_0 | ED_CR_STP);
-		if (bus_space_read_1(nict, nich, NERTL_RTL0_8019ID0) ==
-								RTL0_8019ID0 &&
-		    bus_space_read_1(nict, nich, NERTL_RTL0_8019ID1) ==
-								RTL0_8019ID1) {
-			typestr = "NE2000 (RTL8019)";
-			dsc->sc_mediachange = rtl80x9_mediachange;
-			dsc->sc_mediastatus = rtl80x9_mediastatus;
-			dsc->init_card = rtl80x9_init_card;
-			dsc->sc_media_init = rtl80x9_media_init;
-		}
+		break;
+
+	case NE2000_TYPE_RTL8019:
+		typestr = "NE2000 (RTL8019)";
 		break;
 
 	default:

Index: src/sys/dev/isapnp/if_ne_isapnp.c
diff -u src/sys/dev/isapnp/if_ne_isapnp.c:1.26 src/sys/dev/isapnp/if_ne_isapnp.c:1.27
--- src/sys/dev/isapnp/if_ne_isapnp.c:1.26	Mon Apr 28 20:23:53 2008
+++ src/sys/dev/isapnp/if_ne_isapnp.c	Wed Mar  3 13:39:57 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_ne_isapnp.c,v 1.26 2008/04/28 20:23:53 martin Exp $	*/
+/*	$NetBSD: if_ne_isapnp.c,v 1.27 2010/03/03 13:39:57 tsutsui Exp $	*/
 
 /*-
  * Copyright (c) 1997, 1998 The NetBSD Foundation, Inc.
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_ne_isapnp.c,v 1.26 2008/04/28 20:23:53 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_ne_isapnp.c,v 1.27 2010/03/03 13:39:57 tsutsui Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -57,9 +57,6 @@
 #include <dev/ic/ne2000reg.h>
 #include <dev/ic/ne2000var.h>
 
-#include <dev/ic/rtl80x9reg.h>
-#include <dev/ic/rtl80x9var.h>
-
 #include <dev/isa/isavar.h>
 
 #include <dev/isapnp/isapnpreg.h>
@@ -142,21 +139,10 @@
 
 	case NE2000_TYPE_NE2000:
 		typestr = "NE2000";
-		/*
-		 * Check for a Realtek 8019.
-		 */
-		bus_space_write_1(nict, nich, ED_P0_CR,
-		    ED_CR_PAGE_0 | ED_CR_STP);
-		if (bus_space_read_1(nict, nich, NERTL_RTL0_8019ID0) ==
-								RTL0_8019ID0 &&
-		    bus_space_read_1(nict, nich, NERTL_RTL0_8019ID1) ==
-								RTL0_8019ID1) {
-			typestr = "NE2000 (RTL8019)";
-			dsc->sc_mediachange = rtl80x9_mediachange;
-			dsc->sc_mediastatus = rtl80x9_mediastatus;
-			dsc->init_card = rtl80x9_init_card;
-			dsc->sc_media_init = rtl80x9_media_init;
-		}
+		break;
+
+	case NE2000_TYPE_RTL8019:
+		typestr = "NE2000 (RTL8019)";
 		break;
 
 	default:

Reply via email to