Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 2 Aug 1998 11:54:30 +0100 (BST)
From:      Robert Swindells <rjs@fdy2.demon.co.uk>
To:        se@FreeBSD.ORG
Cc:        faber@isi.edu, fmc@reanimators.org, mike@smith.net.au, hackers@FreeBSD.ORG
Subject:   Re: AMD PCNet/FAST cards; suppliers?
Message-ID:  <199808021054.LAA00638@fdy2.demon.co.uk>
In-Reply-To: <19980801211533.D267@mi.uni-koeln.de> (message from Stefan Esser on Sat, 1 Aug 1998 21:15:33 %2B0200)

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

[Questions about previous mod deleted]

> Ted Faber wrote:
>> On the other hand Robert Swindells's driver seems to attach the chip
>> as a PCI device and work fine.  If his modifications are small and
>> acceptable, maybe the best plan is to incorporate them.  If his mods

>I'd like to understand what's different in that new
>driver. The current driver worked well with the AMD
>PCnet found on many motherboards, and IMHO we need 
>to make sure that the new driver supports the whole
>range of Lance chips ...

I haven't written a new driver, just made minor changes to the old one.

The changes are:

 * Add probing support for the chip IDs for newer PCnet chips - 79c970A,
   79c971 and 79c972.

 * Add support for reading and writing the BCR registers. Not currently
   used, but you need it to be able to add ifmedia support.

 * Modify pcnet_probe() to always return the chip type even if it is a
   PCI device. The probe routines that call this now check for the
   returned chip type when determining whether to attach it.

Things not done:

 * No probe for 79c960A (PCnet-ISA II)

 * The chip ID for the 79c970 doesn't look right. It may be that the probe
   for this only worked because there was no distinction between "Unknown"
   and "PCI".

I'll check into these two before doing a send-pr.

The diffs are:

--- if_lnc.h.orig	Sun Jul 26 23:00:22 1998
+++ if_lnc.h	Tue Jul 28 23:17:52 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,9 +71,12 @@
 #define LANCE           1        /* Am7990   */
 #define C_LANCE         2        /* Am79C90  */
 #define PCnet_ISA       3        /* Am79C960 */
-#define PCnet_ISAplus  4        /* Am79C961 */
+#define PCnet_ISAplus   4        /* Am79C961 */
 #define PCnet_32        5        /* Am79C965 */
 #define PCnet_PCI       6        /* Am79C970 */
+#define PCnet_PCI_II    7        /* Am79C970A */
+#define PCnet_FAST      8        /* Am79C971 */
+#define PCnet_FASTplus  9        /* Am79C972 */
 
 /* CSR88-89: Chip ID masks */
 #define AMD_MASK  0x003
@@ -83,7 +85,9 @@
 #define Am79C961  0x2260
 #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	Wed Jul 29 00:06:23 1998
@@ -122,6 +122,7 @@
 	int initialised;
 	int rap;
 	int rdp;
+	int bdp;
 #ifdef DEBUG
 	int lnc_debug;
 #endif
@@ -145,7 +146,10 @@
 	"PCnet-ISA",
 	"PCnet-ISA+",
 	"PCnet-32 VL-Bus",
-	"PCnet-PCI",		/* "can't happen" */
+	"PCnet-PCI",
+	"PCnet-PCI II",
+	"PCnet-FAST",
+	"PCnet-FAST+",
 };
 
 #ifdef LNC_MULTICAST
@@ -203,6 +207,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 +963,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 +1019,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;
 
@@ -1154,18 +1174,13 @@
 			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 +1232,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 +1295,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 +1306,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 +1556,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 +1957,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);
 }


Robert Swindells
-------------------------------------
Robert Swindells     - GenRad Ltd
rjs@genrad.co.uk     - Work
rjs@fdy2.demon.co.uk - Home

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



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