Subject: kern/23428: driver support for NDC NCP130A2 (Prism-II PCI)
To: None <gnats-bugs@gnats.netbsd.org>
From: None <tmp@ariel.plethora.net>
List: netbsd-bugs
Date: 11/13/2003 19:42:41
>Number:         23428
>Category:       kern
>Synopsis:       device chipset supported, but attach lacks support for board
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    kern-bug-people
>State:          open
>Class:          support
>Submitter-Id:   net
>Arrival-Date:   Fri Nov 14 01:43:00 UTC 2003
>Closed-Date:
>Last-Modified:
>Originator:     T. M. Pederson
>Release:        NetBSD 1.6ZE (2003-11-13)
>Organization:
Plethora . Net
>Environment:
	
	
System: NetBSD thule.mirage 1.6ZE NetBSD 1.6ZE (SNAFU) #13: Wed Nov 13 11:58:50 CST 2003 tmp@thule.mirage:/usr/src/sys/arch/i386/compile/SNAFU i386
Architecture: i386
Machine: i386
>Description:
	While the Prism-II chipset on board the Nat'l Datacomm Corp. NCP130
	rev. A2 appears to be supported, the PCI<->Prism bridge lacks a
	function to initialize it.
>How-To-Repeat:
	Install the NDC NCP130A2 board in a NetBSD system and provide
	electricity.
>Fix:
	Apply the following two diffs, The cover two critical addresses for
	wireg.h and a preliminary function for initializing the board. I've
	done some initial tests with a board I have, and it looks good so
	far. A note on the function rewrite: I tried sticking with
	if/then/else, and PLX gets its own variables, but that got cumbersome.

--- sys/dev/ic/wireg.h.orig	2003-11-03 15:18:06.000000000 -0600
+++ sys/dev/ic/wireg.h	2003-11-05 10:40:11.000000000 -0600
@@ -228,6 +228,9 @@
 #define WI_HCR_HOLD		0x000f
 #define WI_HCR_EEHOLD		0x00ce
 
+#define WI_TMD_COR		0x14	/* Prism COR (TMD) */
+#define WI_TMD_IO		0x18	/* Prism I/O space (TMD) */
+
 /*
  * PCI Host Interface Registers (HFA3842 Specific)
  * The value of all Register's Offset, such as WI_INFO_FID and WI_PARAM0,


--- sys/dev/pci/if_wi_pci.c.orig	2003-10-24 15:49:49.000000000 -0500
+++ sys/dev/pci/if_wi_pci.c	2003-11-05 12:35:00.000000000 -0600
@@ -79,6 +79,7 @@
 
 #define CHIP_PLX_OTHER		0x01
 #define CHIP_PLX_9052		0x02
+#define CHIP_TMD_7160		0x03
 
 #define WI_PLX_COR_OFFSET       0x3E0
 #define WI_PLX_COR_VALUE        0x41
@@ -110,7 +111,7 @@
 	pci_vendor_id_t		wpp_vendor;	/* vendor ID */
 	pci_product_id_t	wpp_product;	/* product ID */
 	const char		*wpp_name;	/* product name */
-	int			wpp_plx;	/* uses PLX chip */
+	int			wpp_chip;	/* uses other chip */
 } wi_pci_products[] = {
 	{ PCI_VENDOR_GLOBALSUN,		PCI_PRODUCT_GLOBALSUN_GL24110P,
 	  NULL, CHIP_PLX_OTHER },
@@ -128,6 +129,8 @@
 	  NULL, CHIP_PLX_9052 },
 	{ PCI_VENDOR_USR2,		PCI_PRODUCT_USR2_2415,
 	  NULL, CHIP_PLX_OTHER },
+	{ PCI_VENDOR_NDC,		PCI_PRODUCT_NDC_NCP130A2,
+	  NULL, CHIP_TMD_7160 },
 	{ 0,				0,
 	  NULL, 0},
 };
@@ -235,8 +238,8 @@
 	const char *intrstr;
 	const struct wi_pci_product *wpp;
 	pci_intr_handle_t ih;
-	bus_space_tag_t memt, iot, plxt;
-	bus_space_handle_t memh, ioh, plxh;
+	bus_space_tag_t memt, iot, plxt, tmdt;
+	bus_space_handle_t memh, ioh, plxh, tmdh;
 
 	psc->psc_pc = pc;
 
@@ -248,7 +251,9 @@
 	}
 #endif
 
-	if (wpp->wpp_plx) {
+	switch (wpp->wpp_chip) {
+	case CHIP_PLX_OTHER:
+	case CHIP_PLX_9052:
 		/* Map memory and I/O registers. */
 		if (pci_mapreg_map(pa, WI_PCI_LOMEM, PCI_MAPREG_TYPE_MEM, 0,
 		    &memt, &memh, NULL, NULL) != 0) {
@@ -261,7 +266,7 @@
 			return;
 		}
 
-		if (wpp->wpp_plx == CHIP_PLX_OTHER) {
+		if (wpp->wpp_chip == CHIP_PLX_OTHER) {
 			/* The PLX 9052 doesn't have IO at 0x14.  Perhaps
 			   other chips have, so we'll make this conditional. */
 			if (pci_mapreg_map(pa, WI_PCI_PLX_LOIO,
@@ -271,7 +276,25 @@
 					return;
 				}
 		}
-	} else {
+		break;
+	case CHIP_TMD_7160:
+		/* Used instead of PLX on at least one revision of the
+		 * Nat'l Datacomm Corp. NCP130. Value for registers
+		 * acquired from OpenBSD, which in turn got them from
+		 * a linux driver. */
+		/* Map COR and I/O registers. */
+		if (pci_mapreg_map(pa, WI_TMD_COR, PCI_MAPREG_TYPE_IO, 0,
+		    &tmdt, &tmdh, NULL, NULL) != 0) {
+			printf(": can't map TMD I/O space\n");
+			return;
+		}
+		if (pci_mapreg_map(pa, WI_TMD_IO, PCI_MAPREG_TYPE_IO, 0,
+		    &iot, &ioh, NULL, NULL) != 0) {
+			printf(": can't map I/O space\n");
+			return;
+		}
+		break;
+	default:
 		if (pci_mapreg_map(pa, WI_PCI_CBMA,
 		    PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT,
 		    0, &iot, &ioh, NULL, NULL) != 0) {
@@ -282,6 +305,7 @@
 		memt = iot;
 		memh = ioh;
 		sc->sc_pci = 1;
+		break;
 	}
 
 	if (wpp->wpp_name != NULL) {
@@ -304,7 +328,7 @@
 	CSR_WRITE_2(sc, WI_INT_EN, 0);
 	CSR_WRITE_2(sc, WI_EVENT_ACK, 0xFFFF);
 
-	if (wpp->wpp_plx == CHIP_PLX_OTHER) {
+	if (wpp->wpp_chip == CHIP_PLX_OTHER) {
 		uint32_t command;
 #define	WI_LOCAL_INTCSR		0x4c
 #define	WI_LOCAL_INTEN		0x40	/* poke this into INTCSR */
@@ -334,16 +358,27 @@
 
 	printf("%s: interrupting at %s\n", sc->sc_dev.dv_xname, intrstr);
 
-	if (wpp->wpp_plx) {
+	switch (wpp->wpp_chip) {
+	case CHIP_PLX_OTHER:
+	case CHIP_PLX_9052:
 		/*
 		 * Setup the PLX chip for level interrupts and config index 1
 		 * XXX - should really reset the PLX chip too.
 		 */
 		bus_space_write_1(memt, memh,
 		    WI_PLX_COR_OFFSET, WI_PLX_COR_VALUE);
-	} else {
+		break;
+	case CHIP_TMD_7160:
+		/*
+		 * Enable I/O mode and level interrupts on the embedded
+		 * card. The card's COR is the first byte of BAR 0.
+		 */
+		bus_space_write_1(tmdt, tmdh, 0, WI_COR_IOMODE);
+		break;
+	default:
 		/* reset HFA3842 MAC core */
 		wi_pci_reset(sc);
+		break;
 	}
 
 	printf("%s:", sc->sc_dev.dv_xname);
>Release-Note:
>Audit-Trail:
>Unformatted: