Subject: port-alpha/4595: Fix for NE2000 on alpha architecture
To: None <gnats-bugs@gnats.netbsd.org>
From: None <ajo@wopr.campus.luth.se>
List: netbsd-bugs
Date: 11/28/1997 20:00:04
>Number:         4595
>Category:       port-alpha
>Synopsis:       Fix for NE2000 on alpha architecture
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    gnats-admin (GNATS administrator)
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Fri Nov 28 10:05:00 1997
>Last-Modified:
>Originator:     Andreas Johansson
>Organization:
Nisses bilverkstad
>Release:        NetBSD-1.3_ALPHA
>Environment:
axppci33
System: NetBSD wopr 1.3_ALPHA NetBSD 1.3_ALPHA (WOPR) #21: Wed Nov 26 20:02:50 CET 1997 root@:/mnt/netbsd/src/sys/arch/alpha/compile/WOPR alpha


>Description:
NE2000 (clones) doesn't work on the alpha architecture. Actually two problems:
1. The SRM console initializes some interrupts to be level-triggered, causing
   the NE2000 to lock the machine completely upon initialization.
2. The NE2000/dp8390 driver had two alignment problems causing kernel panics
   at some occations.
>How-To-Repeat:
Try using the NE2000 driver :)
>Fix:
This might not be the "correct way" to fix it, but it works well for me.
The BROKEN_PROM_CONSOLE fix must be done in a different way, checking the
hardware at boot time since just compiling in support for the AlphaStation
machines will enable the define, disabling the NE2000.

--- dev/ic/dp8390.c.orig	Mon Nov 24 02:46:34 1997
+++ dev/ic/dp8390.c	Mon Nov 24 02:48:09 1997
@@ -1076,6 +1076,16 @@
 			}
 			len = MCLBYTES;
 		}
+
+		if (top == 0)  {
+			/* align the struct ip header */
+			caddr_t newdata = (caddr_t)
+                            ALIGN(m->m_data + sizeof(struct ether_header))
+                            - sizeof(struct ether_header);
+                        len -= newdata - m->m_data;
+                        m->m_data = newdata;
+                }
+
 		m->m_len = len = min(total_len, len);
 		if (sc->ring_copy)
 			src = (*sc->ring_copy)(sc, src, mtod(m, caddr_t), len);
--- arch/alpha/pci/pci_swiz_bus_io_chipdep.c.orig	Wed Nov 26 16:47:51 1997
+++ arch/alpha/pci/pci_swiz_bus_io_chipdep.c	Fri Nov 28 15:25:43 1997
@@ -646,11 +646,44 @@
 	bus_size_t o, c;						\
 	const TYPE *a;							\
 {									\
+	/* Check for unaligned access to memory */			\
+	if ((BYTES > 1) && ( ((u_int64_t)a) & (BYTES-1) ) ) {		\
+	    TYPE d;							\
+	    int  i;							\
 									\
-	while (c-- > 0) {						\
-		__C(__C(CHIP,_io_write_),BYTES)(v, h, o, *a++);		\
-		__C(CHIP,_io_barrier)(v, h, o, sizeof *a,		\
-		    BUS_BARRIER_WRITE);					\
+	    if (((u_int64_t)a) & 1) {					\
+		while (c-- > 0) {					\
+			for (i = 0; i < BYTES; i++)			\
+				((u_int8_t *)&d)[i] = *((u_int8_t *)a)++; \
+			__C(__C(CHIP,_io_write_),BYTES)(v, h, o, d);	\
+			__C(CHIP,_io_barrier)(v, h, o, sizeof *a,	\
+			    BUS_BARRIER_WRITE);				\
+		}							\
+	    }								\
+	    else if ((BYTES > 2) && (((u_int64_t)a) & 2)) {		\
+		while (c-- > 0) {					\
+			for (i = 0; i < BYTES/2; i++)			\
+				((u_int16_t *)&d)[i] = *((u_int16_t *)a)++; \
+			__C(__C(CHIP,_io_write_),BYTES)(v, h, o, d);	\
+			__C(CHIP,_io_barrier)(v, h, o, sizeof *a,	\
+			    BUS_BARRIER_WRITE);				\
+		}							\
+	    }								\
+	    else if ((BYTES > 4) && (((u_int64_t)a) & 4)) {		\
+		while (c-- > 0) {					\
+			for (i = 0; i < BYTES/4; i++)			\
+				((u_int32_t *)&d)[i] = *((u_int32_t *)a)++; \
+			__C(__C(CHIP,_io_write_),BYTES)(v, h, o, d);	\
+			__C(CHIP,_io_barrier)(v, h, o, sizeof *a,	\
+			    BUS_BARRIER_WRITE);				\
+		}							\
+	    }								\
+	} else {							\
+		while (c-- > 0) {					\
+			__C(__C(CHIP,_io_write_),BYTES)(v, h, o, *a++);	\
+			__C(CHIP,_io_barrier)(v, h, o, sizeof *a,	\
+			    BUS_BARRIER_WRITE);				\
+		}							\
 	}								\
 }
 CHIP_io_write_multi_N(1,u_int8_t)
--- arch/alpha/pci/sio_pic.c.orig	Fri Nov 28 15:14:20 1997
+++ arch/alpha/pci/sio_pic.c	Fri Nov 28 15:20:57 1997
@@ -57,8 +57,18 @@
  * started, we're not going to EVER turn it off...  I don't know
  * what will happen if new interrupts (that the PROM console doesn't
  * want) are turned on.  I'll burn that bridge when I come to it.
+ *
+ * Note! The SRM console initializes some interrupts to level-triggered,
+ * and with the BROKEN_PROM_CONSOLE option this is promoted to the
+ * initial state of the interrupt. This breaks the shared interrupt
+ * allocation of the NE2000 since it can't change the type of interrupt
+ * to flank-triggered if it's initially enabled. So, don't define
+ * BROKEN_PROM_CONSOLE when using SRM and NE2000. This may happen
+ * to other cards as well.
  */
+#if defined(DEC_2100_A50) || defined (DEC_KN20AA)
 #define	BROKEN_PROM_CONSOLE
+#endif
 
 /*
  * Private functions and variables.
>Audit-Trail:
>Unformatted: