Subject: port-mac68k/14455: ae driver only probes 32K of buffer RAM
To: None <gnats-bugs@gnats.netbsd.org>
From: Hauke Fath <hauke@Espresso.Rhein-Neckar.DE>
List: netbsd-bugs
Date: 11/04/2001 15:24:52
>Number:         14455
>Category:       port-mac68k
>Synopsis:       ae driver only probes 32K of buffer RAM
>Confidential:   no
>Severity:       serious
>Priority:       low
>Responsible:    port-mac68k-maintainer
>State:          open
>Class:          change-request
>Submitter-Id:   net
>Arrival-Date:   Sun Nov 04 06:30:00 PST 2001
>Closed-Date:
>Last-Modified:
>Originator:     Hauke Fath <hauke@Espresso.Rhein-Neckar.DE>
>Release:        NetBSD 1.5Y
>Organization:
Einzeln auftretender Radfahrer
>Environment:
	
System: NetBSD q700.causeuse.org 1.5Y NetBSD 1.5Y (FG54) #0: Wed Oct 3 20:38:30 CEST 2001 hauke@q700.causeuse.org:/home/hauke/work/netbsd/current/sys/arch/mac68k/compile/FG54 mac68k
Architecture: m68k
Machine: mac68k


>Description:

"Apple compatible" Nubus ethernet cards that are supported by
the 'ae' driver come with onboard RAM buffer in various sizes and
memory layouts.

The current driver only probes max. 32KByte of RAM. There are cards
with 64K buffers, and with a slow machine on a busy ethernet segment,
you need the extra space.

See the discussions on

"ae driver probing max. 32k RAM -- why?"
http://mail-index.netbsd.org/port-mac68k/1999/12/
http://mail-index.netbsd.org/port-mac68k/1999/12/14/0012.html

"AE memory size"
http://mail-index.netbsd.org/port-mac68k/2001/09/
http://mail-index.netbsd.org/port-mac68k/2001/09/21/0000.html

"64k on ae ethernet - followup"
http://mail-index.netbsd.org/port-mac68k/2001/10/22/0000.html

The latter has extensive tests performed by John Klos on several
ethernet cards.


>How-To-Repeat:

See

ae0 at nubus0 slot d: Ethernet A-Series, 32KB memory
ae0: Ethernet address 00:40:10:02:0f:26

in the boot log when the ethernet card clearly has more RAM. Watch
receive buffer overflows in /var/log/messages, UTSL and scratch your
head.


>Fix:

Apply the following patch which probes 64K of buffer RAM, reverses the
probe sequence to avoid false positives and adds a few comments:


--- if_ae.c	Wed Sep 13 07:21:16 2000
+++ if_ae.c.patched	Sun Nov  4 15:02:09 2001
@@ -37,34 +37,55 @@
 	bus_space_handle_t bsh;
 	int ofs;
 {
-	int i1, i2, i3, i4;
+	int i1, i2, i3, i4, i8;
 
 	/*
-	 * banks; also assume it will generally mirror in upper banks
-	 * if not installed.
+	 * banks of 8K; also assume it will generally mirror
+	 * in upper banks if not installed.
 	 */
 	i1 = (8192 * 0);
 	i2 = (8192 * 1);
 	i3 = (8192 * 2);
 	i4 = (8192 * 3);
+	i8 = (8192 * 4);
 
-	bus_space_write_2(bst, bsh, ofs + i1, 0x1111);
-	bus_space_write_2(bst, bsh, ofs + i2, 0x2222);
-	bus_space_write_2(bst, bsh, ofs + i3, 0x3333);
+	/*
+	 * 1) If the memory range is decoded completely, it does not 
+	 *    matter what we write first: High tags written into 
+	 *    the void are lost. 
+	 * 2) If the memory range is not decoded completely (banks are 
+	 *    mirrored), high tags are overwritten by lower ones.
+	 * 3) Lazy implementation of pathological cases.
+	 */
+	bus_space_write_2(bst, bsh, ofs + i8, 0x8888);
 	bus_space_write_2(bst, bsh, ofs + i4, 0x4444);
+	bus_space_write_2(bst, bsh, ofs + i3, 0x3333);
+	bus_space_write_2(bst, bsh, ofs + i2, 0x2222);
+	bus_space_write_2(bst, bsh, ofs + i1, 0x1111);
+
+	/* Eight banks at 1-8 */
+	if (bus_space_read_2(bst, bsh, ofs + i1) == 0x1111 &&
+	    bus_space_read_2(bst, bsh, ofs + i2) == 0x2222 &&
+	    bus_space_read_2(bst, bsh, ofs + i3) == 0x3333 &&
+	    bus_space_read_2(bst, bsh, ofs + i4) == 0x4444 &&
+	    bus_space_read_2(bst, bsh, ofs + i8) == 0x8888)
+		return 8192 * 8;
 
+	/* Four banks at 1-4 */
 	if (bus_space_read_2(bst, bsh, ofs + i1) == 0x1111 &&
 	    bus_space_read_2(bst, bsh, ofs + i2) == 0x2222 &&
 	    bus_space_read_2(bst, bsh, ofs + i3) == 0x3333 &&
 	    bus_space_read_2(bst, bsh, ofs + i4) == 0x4444)
 		return 8192 * 4;
 
+	/* Two banks either at 1&2 or at 3&4 (relevant?) */
 	if ((bus_space_read_2(bst, bsh, ofs + i1) == 0x1111 &&
 	    bus_space_read_2(bst, bsh, ofs + i2) == 0x2222) ||
 	    (bus_space_read_2(bst, bsh, ofs + i1) == 0x3333 &&
 	    bus_space_read_2(bst, bsh, ofs + i2) == 0x4444))
 		return 8192 * 2;
 
+	/* Onae bank either at 1 or at 4 (relevant?) */
 	if (bus_space_read_2(bst, bsh, ofs + i1) == 0x1111 ||
 	    bus_space_read_2(bst, bsh, ofs + i1) == 0x4444)
 		return 8192;
>Release-Note:
>Audit-Trail:
>Unformatted: