Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 6 Aug 1998 23:15:15 +0100 (BST)
From:      rjs@fdy2.demon.co.uk
To:        FreeBSD-gnats-submit@FreeBSD.ORG
Subject:   kern/7511: if_lnc network driver probe failure
Message-ID:  <199808062215.XAA00711@fdy2.demon.co.uk>

next in thread | raw e-mail | index | archive | help

>Number:         7511
>Category:       kern
>Synopsis:       if_lnc network driver probe failure
>Confidential:   no
>Severity:       serious
>Priority:       high
>Responsible:    freebsd-bugs
>State:          open
>Quarter:
>Keywords:
>Date-Required:
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Thu Aug  6 15:30:01 PDT 1998
>Last-Modified:
>Originator:     Robert Swindells
>Organization:
GenRad Ltd
>Release:        FreeBSD 2.2.7-STABLE i386
>Environment:

	AMD PCnet PCI series network cards.

>Description:

	The if_lnc driver does not probe correctly for all models of
	AMD PCI network card.

>How-To-Repeat:

	Attempt to use if_lnc driver with PCnet-PCI II or PCnet-FAST
	network cards.

>Fix:
	diff -u of sys/i386/isa/if_lnc.c and sys/i386/isa/if_lnc.h

--- if_lnc.h.orig	Sun Jul 26 23:00:22 1998
+++ if_lnc.h	Sun Aug  2 12:19:09 1998
@@ -41,8 +41,7 @@
 #define PCNET_RDP    0x10        /* Register Data Port */
 #define PCNET_RAP    0x12        /* Register Address Port */
 #define PCNET_RESET  0x14
-#define PCNET_IDP    0x16
-#define PCNET_VSW    0x18
+#define PCNET_BDP    0x16
 
 /* DEPCA port addresses */
 #define DEPCA_IOSIZE   16
@@ -72,18 +71,25 @@
 #define LANCE           1        /* Am7990   */
 #define C_LANCE         2        /* Am79C90  */
 #define PCnet_ISA       3        /* Am79C960 */
-#define PCnet_ISAplus  4        /* Am79C961 */
-#define PCnet_32        5        /* Am79C965 */
-#define PCnet_PCI       6        /* Am79C970 */
+#define PCnet_ISAplus   4        /* Am79C961 */
+#define PCnet_ISA_II    5        /* Am79C961A */
+#define PCnet_32        6        /* Am79C965 */
+#define PCnet_PCI       7        /* Am79C970 */
+#define PCnet_PCI_II    8        /* Am79C970A */
+#define PCnet_FAST      9        /* Am79C971 */
+#define PCnet_FASTplus  10       /* Am79C972 */
 
 /* CSR88-89: Chip ID masks */
 #define AMD_MASK  0x003
 #define PART_MASK 0xffff
 #define Am79C960  0x0003
 #define Am79C961  0x2260
+#define Am79C961A 0x2261
 #define Am79C965  0x2430
 #define Am79C970  0x0242
-#define HITACHI_Am79C970  0x2621
+#define Am79C970A 0x2621
+#define Am79C971  0x2623
+#define Am79C972  0x2624
 
 /* Board types */
 #define UNKNOWN         0

--- if_lnc.c.orig	Sun Jul 26 23:00:15 1998
+++ if_lnc.c	Sun Aug  2 12:20:34 1998
@@ -122,6 +122,7 @@
 	int initialised;
 	int rap;
 	int rdp;
+	int bdp;
 #ifdef DEBUG
 	int lnc_debug;
 #endif
@@ -144,8 +145,12 @@
 	"C-LANCE",
 	"PCnet-ISA",
 	"PCnet-ISA+",
+	"PCnet-ISA II",
 	"PCnet-32 VL-Bus",
-	"PCnet-PCI",		/* "can't happen" */
+	"PCnet-PCI",
+	"PCnet-PCI II",
+	"PCnet-FAST",
+	"PCnet-FAST+",
 };
 
 #ifdef LNC_MULTICAST
@@ -203,6 +208,20 @@
 	return (inw(sc->rdp));
 }
 
+static __inline void
+write_bcr(struct lnc_softc *sc, u_short port, u_short val)
+{
+	outw(sc->rap, port);
+	outw(sc->bdp, val);
+}
+
+static __inline u_short
+read_bcr(struct lnc_softc *sc, u_short port)
+{
+	outw(sc->rap, port);
+	return (inw(sc->bdp));
+}
+
 #ifdef LNC_MULTICAST
 static __inline u_long
 ether_crc(u_char *ether_addr)
@@ -945,7 +964,8 @@
 	outw(iobase + CNET98S_RESET, tmp);
 	DELAY(500);
 
-	if ((sc->nic.ic = pcnet_probe(sc)) == UNKNOWN) {
+	sc->nic.ic = pcnet_probe(sc);
+	if ((sc->nic.ic == UNKNOWN) || (sc->nic.ic > PCnet_32)) {
 		return (0);
 	}
 
@@ -1000,7 +1020,8 @@
 	sc->rap = iobase + PCNET_RAP;
 	sc->rdp = iobase + PCNET_RDP;
 
-	if ((sc->nic.ic = pcnet_probe(sc))) {
+	sc->nic.ic = pcnet_probe(sc);
+	if ((sc->nic.ic > 0) && (sc->nic.ic < PCnet_PCI)) {
 		sc->nic.ident = NE2100;
 		sc->nic.mem_mode = DMA_FIXED;
 
@@ -1151,21 +1172,18 @@
 				return (PCnet_ISA);
 			case Am79C961:
 				return (PCnet_ISAplus);
+			case Am79C961A:
+				return (PCnet_ISA_II);
 			case Am79C965:
 				return (PCnet_32);
 			case Am79C970:
-			    /*
-			     * do NOT try to ISA attach the PCI version
-			     */
-				return (0);
-			case HITACHI_Am79C970:
-
-                            /*
-			     * PCI cards that should be attached in
-			     * ISA mode should return this value. -- tvf
-			     */
-
-			        return (PCnet_PCI);
+				return (PCnet_PCI);
+			case Am79C970A:
+				return (PCnet_PCI_II);
+			case Am79C971:
+				return (PCnet_FAST);
+			case Am79C972:
+				return (PCnet_FASTplus);
 			default:
 				break;
 			}
@@ -1217,7 +1235,9 @@
 	 */
 	if ((sc->nic.mem_mode != SHMEM) && (kvtop(sc->recv_ring) > 0x1000000)) {
 		log(LOG_ERR, "lnc%d: Memory allocated above 16Mb limit\n", unit);
-		if (sc->nic.ic != PCnet_PCI)
+		if ((sc->nic.ic != PCnet_PCI) &&
+		    (sc->nic.ic != PCnet_PCI_II) &&
+		    (sc->nic.ic != PCnet_FAST))
 			return (0);
 	}
 
@@ -1278,8 +1298,7 @@
 	 *       and ether_ifattach() have been called in lnc_attach() ???
 	 */
 	if ((sc->nic.mem_mode != SHMEM) &&
-		 (sc->nic.ic != PCnet_32) &&
-		 (sc->nic.ic != PCnet_PCI))
+		 (sc->nic.ic < PCnet_32))
 		isa_dmacascade(isa_dev->id_drq);
 #endif
 
@@ -1290,22 +1309,35 @@
 void *
 lnc_attach_ne2100_pci(int unit, unsigned iobase)
 {
+	int i;
 	struct lnc_softc *sc = malloc(sizeof *sc, M_DEVBUF, M_NOWAIT);
 
 	if (sc) {
 		bzero (sc, sizeof *sc);
 
-		/*
-		 * ne2100_probe sets sc->nic.ic to PCnet_PCI for PCI
-		 * cards that work in ISA emulation mode. The first
-		 * clause this code avoids attaching such a card at
-		 * this time to allow it to be picked up as an ISA
-		 * card later. -- tvf
-		 */
+		sc->rap = iobase + PCNET_RAP;
+		sc->rdp = iobase + PCNET_RDP;
+		sc->bdp = iobase + PCNET_BDP;
+
+		sc->nic.ic = pcnet_probe(sc);
+		if (sc->nic.ic >= PCnet_PCI) {
+			sc->nic.ident = NE2100;
+			sc->nic.mem_mode = DMA_FIXED;
 
-		if (((ne2100_probe(sc, iobase) == 0) ||
-		     sc->nic.ic == PCnet_PCI)
-		    || (lnc_attach_sc(sc, unit) == 0)) {
+			/* XXX - For now just use the defines */
+			sc->nrdre = NRDRE;
+			sc->ntdre = NTDRE;
+
+			/* Extract MAC address from PROM */
+			for (i = 0; i < ETHER_ADDR_LEN; i++)
+				sc->arpcom.ac_enaddr[i] = inb(iobase + i);
+
+			if (lnc_attach_sc(sc, unit) == 0) {
+				free(sc, M_DEVBUF);
+				sc = NULL;
+			}
+		}
+		else {
 			free(sc, M_DEVBUF);
 			sc = NULL;
 		}
@@ -1527,7 +1559,8 @@
 		 * be missed.
 		 */
 
-		outw(sc->rdp, IDON | CERR | BABL | MISS | MERR | RINT | TINT | INEA);
+		/*outw(sc->rdp, IDON | CERR | BABL | MISS | MERR | RINT | TINT | INEA);*/
+		outw(sc->rdp, csr0);
 
 		/* We don't do anything with the IDON flag */
 
@@ -1927,6 +1960,7 @@
 		    ((sc->trans_ring + i)->md->md3 >> 10), TRANS_MD3);
 	printf("\nnext_to_send = %x\n", sc->next_to_send);
 	printf("\n CSR0 = %b CSR1 = %x CSR2 = %x CSR3 = %x\n\n", read_csr(sc, CSR0), CSR0_FLAGS, read_csr(sc, CSR1), read_csr(sc, CSR2), read_csr(sc, CSR3));
+
 	/* Set RAP back to CSR0 */
 	outw(sc->rap, CSR0);
 }
>Audit-Trail:
>Unformatted:

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199808062215.XAA00711>