Subject: kern/9861: rl driver with CardBus attachment can't get MAC address from 9356 EEPROM.
To: None <gnats-bugs@gnats.netbsd.org>
From: None <kanaoka@ann.hi-ho.ne.jp>
List: netbsd-bugs
Date: 04/11/2000 18:13:09
>Number:         9861
>Category:       kern
>Synopsis:       rl driver with CardBus attachment can't get MAC address from 9356 EEPROM.
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    kern-bug-people
>State:          open
>Class:          change-request
>Submitter-Id:   net
>Arrival-Date:   Tue Apr 11 18:14:00 PDT 2000
>Closed-Date:
>Last-Modified:
>Originator:     Masanori Kanaoka
>Release:        NetBSD-current(1.4X)
>Organization:
>Environment:
NetBSD kana1.ann.hi-ho.ne.jp 1.4X NetBSD 1.4X (PCIBIOS) #10: Tue Apr 11 19:24:15 JST 2000     root@kana1.ann.hi-ho.ne.jp:/usr/src/sys/arch/i386/compile/PCIBIOS i386


>Description:
rl_read_eeprom() support only 9346 EEPROM,
but rl CardBus card has 9356 EEPROM.

rl driver with CardBus attachment get MAC address 
from RL-IDR0,...,RL-IDR5 registers instead of 
getting MAC address from EEPROM.

I refine rl_read_eeprom() that support 9346 EEPROM 
and 9356 EEPROM.rl driver with CardBus attachment 
get MAC address from 9356 EEPROM.

Please apply next patch

>How-To-Repeat:


>Fix:

Index: sys/dev/cardbus/if_rl_cardbus.c
===================================================================
RCS file: /home/ftp/cvs/syssrc/sys/dev/cardbus/if_rl_cardbus.c,v
retrieving revision 1.1
diff -u -r1.1 if_rl_cardbus.c
--- sys/dev/cardbus/if_rl_cardbus.c	2000/04/10 07:42:57	1.1
+++ sys/dev/cardbus/if_rl_cardbus.c	2000/04/11 10:12:21
@@ -162,11 +162,12 @@
 	struct device *parent, *self;
 	void *aux;
 {
-	int			s;
+	int			s, is56;
 #ifndef RL_USEIOSPACE
 	vm_offset_t		pbase, vbase;
 #endif
 	u_char			eaddr[ETHER_ADDR_LEN];
+	u_int16_t		id;
 	u_int32_t		command;
 	struct rl_cardbus_softc *csc = (struct rl_cardbus_softc *)self;
 	struct rl_softc *sc = &csc->sc_rl;
@@ -286,28 +287,18 @@
 		t->rl_did == CARDBUS_PRODUCT_REALTEK_RT8138){
 		sc->rl_type = RL_8139;
 
+
+		/*
+		 * Check EEPROM type 9346 or 9356
+		 */
+		rl_read_eeprom(sc, (caddr_t)&id, RL_EE_ID, 1, 0, 1);
+		is56 = (id == 0x8129);
+
 		/*
-		 * LD-10/100CBA (ACCTON_MPX5030):
-		 * LPC3-TX-CB   (REALTEK_RT8138):
-		 *     rl_read_eeprom() can't get MAC address 
-		 *     from EEPROM(serial access). Lift MAC address
-		 *     from RL-IDR0 -Rl_IDR5 register.
-		 *
-		 *  RTL8139B(L) datasheet rev 2.4.
-		 *                                 
-		 *    o REGSTER RL_IDR0 - RL_IDR5 address
-		 *                                 
-		 *    o "After the vaild duration of the RSTB pin or
-		 *     autoload command in 9346CR,RTL8139B(L) performs
-		 *     a series of EEPROM read operation from 93C46(93C56)
-		 *     address 00H to 31H."  from 6. EEPROM Contents
+	 	 * Get station address from eeprom	
 		 */
-		eaddr[0] = CSR_READ_1(sc, RL_IDR0);
-		eaddr[1] = CSR_READ_1(sc, RL_IDR1);
-		eaddr[2] = CSR_READ_1(sc, RL_IDR2);
-		eaddr[3] = CSR_READ_1(sc, RL_IDR3);
-		eaddr[4] = CSR_READ_1(sc, RL_IDR4);
-		eaddr[5] = CSR_READ_1(sc, RL_IDR5);
+		rl_read_eeprom(sc, (caddr_t)&eaddr, RL_EE_EADDR, 3, 0, is56);
+
 	} else {
 		printf(": unknown device ID: 0x%x\n", t->rl_did);
 		goto fail;
@@ -332,4 +323,5 @@
 	splx(s);
 	return;
 }
+
 
Index: sys/dev/pci/if_rl_pci.c
===================================================================
RCS file: /home/ftp/cvs/syssrc/sys/dev/pci/if_rl_pci.c,v
retrieving revision 1.1
diff -u -r1.1 if_rl_pci.c
--- sys/dev/pci/if_rl_pci.c	2000/04/10 07:42:56	1.1
+++ sys/dev/pci/if_rl_pci.c	2000/04/11 09:55:04
@@ -303,7 +303,7 @@
 	 * Now read the exact device type from the EEPROM to find
 	 * out if it's an 8129 or 8139.
 	 */
-	rl_read_eeprom(sc, (caddr_t)&rl_did, RL_EE_PCI_DID, 1, 0);
+	rl_read_eeprom(sc, (caddr_t)&rl_did, RL_EE_PCI_DID, 1, 0, 0);
 
 	if (rl_did == PCI_PRODUCT_REALTEK_RT8139 ||
 	    rl_did == PCI_PRODUCT_ACCTON_MPX5030 ||
@@ -328,7 +328,7 @@
 	/*
 	 * Get station address from the EEPROM.
 	 */
-	rl_read_eeprom(sc, (caddr_t)&eaddr, RL_EE_EADDR, 3, 0);
+	rl_read_eeprom(sc, (caddr_t)&eaddr, RL_EE_EADDR, 3, 0, 0);
 
 	/*
 	 * A RealTek chip was detected. Inform the world.
Index: sys/dev/ic/rtl81x9.c
===================================================================
RCS file: /home/ftp/cvs/syssrc/sys/dev/ic/rtl81x9.c,v
retrieving revision 1.1
diff -u -r1.1 rtl81x9.c
--- sys/dev/ic/rtl81x9.c	2000/04/10 07:42:56	1.1
+++ sys/dev/ic/rtl81x9.c	2000/04/11 10:03:46
@@ -156,8 +156,8 @@
 STATIC int rl_ifmedia_upd	__P((struct ifnet *));
 STATIC void rl_ifmedia_sts	__P((struct ifnet *, struct ifmediareq *));
 
-STATIC void rl_eeprom_putbyte	__P((struct rl_softc *, int));
-STATIC void rl_eeprom_getword	__P((struct rl_softc *, int, u_int16_t *));
+STATIC void rl_eeprom_putbyte	__P((struct rl_softc *, int, int));
+STATIC void rl_eeprom_getword	__P((struct rl_softc *, int, u_int16_t *, int));
 STATIC void rl_mii_sync		__P((struct rl_softc *));
 STATIC void rl_mii_send		__P((struct rl_softc *, u_int32_t, int));
 STATIC int rl_mii_readreg	__P((struct rl_softc *, struct rl_mii_frame *));
@@ -187,18 +187,25 @@
 /*
  * Send a read command and address to the EEPROM, check for ACK.
  */
-STATIC void rl_eeprom_putbyte(sc, addr)
+STATIC void rl_eeprom_putbyte(sc, addr, is56)
 	struct rl_softc		*sc;
 	int			addr;
+	int			is56;
 {
 	register int		d, i;
 
-	d = addr | RL_EECMD_READ;
+	if (is56){
+		d = addr | (RL_EECMD_READ <<2);
+		i = 0x1000;
+	} else {
+		d = addr | RL_EECMD_READ;
+		i = 0x400;
+	}
 
 	/*
 	 * Feed in each bit and stobe the clock.
 	 */
-	for (i = 0x400; i; i >>= 1) {
+	for ( ; i; i >>= 1) {
 		if (d & i) {
 			EE_SET(RL_EE_DATAIN);
 		} else {
@@ -217,10 +224,11 @@
 /*
  * Read a word of data stored in the EEPROM at address 'addr.'
  */
-STATIC void rl_eeprom_getword(sc, addr, dest)
+STATIC void rl_eeprom_getword(sc, addr, dest, is56)
 	struct rl_softc		*sc;
 	int			addr;
 	u_int16_t		*dest;
+	int			is56;
 {
 	register int		i;
 	u_int16_t		word = 0;
@@ -231,7 +239,7 @@
 	/*
 	 * Send address of word we want to read.
 	 */
-	rl_eeprom_putbyte(sc, addr);
+	rl_eeprom_putbyte(sc, addr, is56);
 
 	CSR_WRITE_1(sc, RL_EECMD, RL_EEMODE_PROGRAM|RL_EE_SEL);
 
@@ -258,18 +266,19 @@
 /*
  * Read a sequence of words from the EEPROM.
  */
-void rl_read_eeprom(sc, dest, off, cnt, swap)
+void rl_read_eeprom(sc, dest, off, cnt, swap, is56)
 	struct rl_softc		*sc;
 	caddr_t			dest;
 	int			off;
 	int			cnt;
 	int			swap;
+	int			is56;
 {
 	int			i;
 	u_int16_t		word = 0, *ptr;
 
 	for (i = 0; i < cnt; i++) {
-		rl_eeprom_getword(sc, off + i, &word);
+		rl_eeprom_getword(sc, off + i, &word, is56);
 		ptr = (u_int16_t *)(dest + (i * 2));
 		if (swap)
 			*ptr = ntohs(word);
@@ -589,7 +598,7 @@
 	caddr_t			addr;
 {
 	u_int32_t		crc, carry;
-	int			i, j;
+	int			i,j ;
 	u_int8_t		c;
 
 	/* Compute CRC for the address value. */
Index: sys/dev/ic/rtl81x9reg.h
===================================================================
RCS file: /home/ftp/cvs/syssrc/sys/dev/ic/rtl81x9reg.h,v
retrieving revision 1.1
diff -u -r1.1 rtl81x9reg.h
--- sys/dev/ic/rtl81x9reg.h	2000/04/10 07:42:56	1.1
+++ sys/dev/ic/rtl81x9reg.h	2000/04/11 09:32:00
@@ -409,6 +409,6 @@
 #ifdef _KERNEL
 void	rl_attach	__P((struct rl_softc *, const u_int8_t *));
 int	rl_intr		__P((void *));
-void	rl_read_eeprom	__P((struct rl_softc *, caddr_t, int, int, int));
+void	rl_read_eeprom	__P((struct rl_softc *, caddr_t, int, int, int, int));
 void	rl_reset	__P((struct rl_softc *));
 #endif /* _KERNEL */

>Release-Note:
>Audit-Trail:
>Unformatted: