Subject: MX98713 ethernet chips
To: None <current-users@NetBSD.ORG, port-i386@NetBSD.ORG>
From: Charles M. Hannum <mycroft@mit.edu>
List: current-users
Date: 03/03/1998 10:53:54
So, I experimented with a PCI fast ethernet card with a Macronix
MX98713 ethernet chip.  This is basically a clone of the DC21140 that
the `de' driver talks to.  There are several board designs that use the
Digital and Macronix chips, as well as another clone by Realtek,
interchangably.

There are basically 3 things that need to be done to make it work:

1) The driver has to recognize the Macronix ID.

2) The driver uses the TULIP_STS_LINKFAIL bit on all chips.  However,
this bit is RESERVED on the 21140, and appears to always be 1 on the
Macronix chip.  This caused the driver to loop in the interrupt
handler.  Obviously, the solution is not to use that bit on chips other
than the 21040 (AFAIK, the only chip it's actually defined on).

3) Even with the changes below, the driver seems to spit out the last
18 packets again rapidly after successfully sending 32 packets.  I have
not attempted to track this down.

Someone should probably finish this up so that we can actually support
these boards.


Index: ic/dc21040reg.h
===================================================================
RCS file: /cvsroot/src/sys/dev/ic/dc21040reg.h,v
retrieving revision 1.14
diff -c -2 -r1.14 dc21040reg.h
*** dc21040reg.h	1998/02/27 13:17:25	1.14
--- dc21040reg.h	1998/03/03 15:39:37
***************
*** 534,541 ****
  
  #define	DEC_VENDORID		0x1011
! #define	CHIPID_21040		0x0002
! #define	CHIPID_21140		0x0009
! #define	CHIPID_21041		0x0014
! #define	CHIPID_21142		0x0019
  #define	PCI_VENDORID(x)		((x) & 0xFFFF)
  #define	PCI_CHIPID(x)		(((x) >> 16) & 0xFFFF)
--- 534,543 ----
  
  #define	DEC_VENDORID		0x1011
! #define	CHIPID_DC21040		0x0002
! #define	CHIPID_DC21140		0x0009
! #define	CHIPID_DC21041		0x0014
! #define	CHIPID_DC21142		0x0019
! #define	MACRONIX_VENDORID	0x10d9
! #define	CHIPID_MX98713		0x0512
  #define	PCI_VENDORID(x)		((x) & 0xFFFF)
  #define	PCI_CHIPID(x)		(((x) >> 16) & 0xFFFF)
Index: pci/if_de.c
===================================================================
RCS file: /cvsroot/src/sys/dev/pci/if_de.c,v
retrieving revision 1.62
diff -c -2 -r1.62 if_de.c
*** if_de.c	1998/02/11 01:28:22	1.62
--- if_de.c	1998/03/03 15:39:37
***************
*** 3259,3264 ****
      sc->tulip_intrmask |= TULIP_STS_NORMALINTR|TULIP_STS_RXINTR|TULIP_STS_TXINTR
  	|TULIP_STS_ABNRMLINTR|TULIP_STS_SYSERROR|TULIP_STS_TXSTOPPED
! 	|TULIP_STS_TXUNDERFLOW|TULIP_STS_TXBABBLE|TULIP_STS_LINKFAIL
! 	|TULIP_STS_RXSTOPPED;
  
      if ((sc->tulip_flags & TULIP_DEVICEPROBE) == 0)
--- 3259,3266 ----
      sc->tulip_intrmask |= TULIP_STS_NORMALINTR|TULIP_STS_RXINTR|TULIP_STS_TXINTR
  	|TULIP_STS_ABNRMLINTR|TULIP_STS_SYSERROR|TULIP_STS_TXSTOPPED
! 	|TULIP_STS_TXUNDERFLOW|TULIP_STS_TXBABBLE|TULIP_STS_RXSTOPPED;
! 
!     if (sc->tulip_chipid == TULIP_21040)
! 	sc->tulip_intrmask |= TULIP_STS_LINKFAIL;
  
      if ((sc->tulip_flags & TULIP_DEVICEPROBE) == 0)
***************
*** 3848,3851 ****
--- 3850,3854 ----
  	    break;
  	}
+ #if 0 /* XXXXX */
  	if (csr & (TULIP_STS_LINKPASS|TULIP_STS_LINKFAIL)) {
  #if defined(TULIP_DEBUG)
***************
*** 3860,3863 ****
--- 3863,3867 ----
  	    tulip_media_print(sc);
  	}
+ #endif
  	if (csr & (TULIP_STS_RXINTR|TULIP_STS_RXNOBUF)) {
  	    u_int32_t misses = TULIP_CSR_READ(sc, csr_missed_frames);
***************
*** 5172,5180 ****
      if (PCI_VENDORID(device_id) != DEC_VENDORID)
  	return NULL;
!     if (PCI_CHIPID(device_id) == CHIPID_21040)
  	return "Digital 21040 Ethernet";
!     if (PCI_CHIPID(device_id) == CHIPID_21041)
  	return "Digital 21041 Ethernet";
!     if (PCI_CHIPID(device_id) == CHIPID_21140) {
  	u_int32_t revinfo = pci_conf_read(config_id, PCI_CFRV) & 0xFF;
  	if (revinfo >= 0x20)
--- 5176,5184 ----
      if (PCI_VENDORID(device_id) != DEC_VENDORID)
  	return NULL;
!     if (PCI_CHIPID(device_id) == CHIPID_DC21040)
  	return "Digital 21040 Ethernet";
!     if (PCI_CHIPID(device_id) == CHIPID_DC21041)
  	return "Digital 21041 Ethernet";
!     if (PCI_CHIPID(device_id) == CHIPID_DC21140) {
  	u_int32_t revinfo = pci_conf_read(config_id, PCI_CFRV) & 0xFF;
  	if (revinfo >= 0x20)
***************
*** 5183,5187 ****
  	    return "Digital 21140 Fast Ethernet";
      }
!     if (PCI_CHIPID(device_id) == CHIPID_21142) {
  	u_int32_t revinfo = pci_conf_read(config_id, PCI_CFRV) & 0xFF;
  	if (revinfo >= 0x20)
--- 5187,5191 ----
  	    return "Digital 21140 Fast Ethernet";
      }
!     if (PCI_CHIPID(device_id) == CHIPID_DC21142) {
  	u_int32_t revinfo = pci_conf_read(config_id, PCI_CFRV) & 0xFF;
  	if (revinfo >= 0x20)
***************
*** 5224,5229 ****
  	return 0;
      id = PCI_CHIPID(id);
!     if (id != CHIPID_21040 && id != CHIPID_21041
! 	    && id != CHIPID_21140 && id != CHIPID_21142)
  	return 0;
      irq = pci_inl(pa, PCI_I_LINE) & 0xFF;
--- 5228,5233 ----
  	return 0;
      id = PCI_CHIPID(id);
!     if (id != CHIPID_DC21040 && id != CHIPID_DC21041
! 	    && id != CHIPID_DC21140 && id != CHIPID_DC21142)
  	return 0;
      irq = pci_inl(pa, PCI_I_LINE) & 0xFF;
***************
*** 5369,5379 ****
      struct pci_attach_args *pa = (struct pci_attach_args *) aux;
  
!     if (PCI_VENDORID(pa->pa_id) != DEC_VENDORID)
! 	return 0;
!     if (PCI_CHIPID(pa->pa_id) == CHIPID_21040
! 	    || PCI_CHIPID(pa->pa_id) == CHIPID_21041
! 	    || PCI_CHIPID(pa->pa_id) == CHIPID_21140
! 	    || PCI_CHIPID(pa->pa_id) == CHIPID_21142)
! 	return 1;
  
      return 0;
--- 5373,5387 ----
      struct pci_attach_args *pa = (struct pci_attach_args *) aux;
  
!     if (PCI_VENDORID(pa->pa_id) == DEC_VENDORID) {
! 	if (PCI_CHIPID(pa->pa_id) == CHIPID_DC21040
! 		|| PCI_CHIPID(pa->pa_id) == CHIPID_DC21041
! 		|| PCI_CHIPID(pa->pa_id) == CHIPID_DC21140
! 		|| PCI_CHIPID(pa->pa_id) == CHIPID_DC21142)
! 	    return 1;
!     }
!     if (PCI_VENDORID(pa->pa_id) == MACRONIX_VENDORID) {
! 	if (PCI_CHIPID(pa->pa_id) == CHIPID_MX98713)
! 	    return 1;
!     }
  
      return 0;
***************
*** 5474,5504 ****
  
      if (PCI_VENDORID(id) == DEC_VENDORID) {
! 	if (PCI_CHIPID(id) == CHIPID_21040) chipid = TULIP_21040;
! 	else if (PCI_CHIPID(id) == CHIPID_21140) {
  	    chipid = (revinfo >= 0x20) ? TULIP_21140A : TULIP_21140;
! 	} else if (PCI_CHIPID(id) == CHIPID_21142) {
  	    chipid = (revinfo >= 0x20) ? TULIP_21143 : TULIP_21142;
  	}
! 	else if (PCI_CHIPID(id) == CHIPID_21041) chipid = TULIP_21041;
! 	else if (PCI_CHIPID(id) == CHIPID_21142) chipid = TULIP_21142;
!     }
!     if (chipid == TULIP_CHIPID_UNKNOWN)
! 	return;
  
!     if ((chipid == TULIP_21040 || chipid == TULIP_DE425) && revinfo < 0x20) {
  #ifdef __FreeBSD__
! 	printf("de%d", unit);
  #endif
! 	printf(": not configured; 21040 pass 2.0 required (%d.%d found)\n",
! 	       revinfo >> 4, revinfo & 0x0f);
! 	return;
!     } else if (chipid == TULIP_21140 && revinfo < 0x11) {
  #ifndef __FreeBSD__
! 	printf("\n");
  #endif
! 	printf("de%d: not configured; 21140 pass 1.1 required (%d.%d found)\n",
! 	       unit, revinfo >> 4, revinfo & 0x0f);
! 	return;
      }
  
  #if defined(__FreeBSD__)
--- 5482,5516 ----
  
      if (PCI_VENDORID(id) == DEC_VENDORID) {
! 	if (PCI_CHIPID(id) == CHIPID_DC21040) chipid = TULIP_21040;
! 	else if (PCI_CHIPID(id) == CHIPID_DC21140) {
  	    chipid = (revinfo >= 0x20) ? TULIP_21140A : TULIP_21140;
! 	} else if (PCI_CHIPID(id) == CHIPID_DC21142) {
  	    chipid = (revinfo >= 0x20) ? TULIP_21143 : TULIP_21142;
  	}
! 	else if (PCI_CHIPID(id) == CHIPID_DC21041) chipid = TULIP_21041;
! 	else if (PCI_CHIPID(id) == CHIPID_DC21142) chipid = TULIP_21142;
  
! 	if ((chipid == TULIP_21040 || chipid == TULIP_DE425)
! 		&& revinfo < 0x20) {
  #ifdef __FreeBSD__
! 	    printf("de%d", unit);
  #endif
! 	    printf(": not configured; 21040 pass 2.0 required (%d.%d found)\n",
! 		   revinfo >> 4, revinfo & 0x0f);
! 	    return;
! 	} else if (chipid == TULIP_21140 && revinfo < 0x11) {
  #ifndef __FreeBSD__
! 	    printf("\n");
  #endif
! 	    printf("de%d: not configured; 21140 pass 1.1 required (%d.%d found)\n",
! 		   unit, revinfo >> 4, revinfo & 0x0f);
! 	    return;
! 	}
      }
+     if (PCI_VENDORID(id) == MACRONIX_VENDORID) {
+ 	if (PCI_CHIPID(id) == CHIPID_MX98713) chipid = TULIP_21140;
+     }
+     if (chipid == TULIP_CHIPID_UNKNOWN)
+ 	return;
  
  #if defined(__FreeBSD__)