Subject: Re: re(4) causes stuck in boot
To: None <F.Lorenzen@gmx.de>
From: Izumi Tsutsui <tsutsui@ceres.dti.ne.jp>
List: current-users
Date: 01/28/2007 09:17:35
F.Lorenzen@gmx.de wrote:

> I've got a new Mainboard with two 8110SC on it. Unfortunately GENERIC
> seems not to support this.
> 
> dmesg (re disabled):
> NetBSD 4.99.9 (GENERIC.RE) #0: Sat Jan 27 23:20:21 CET 2007
>         root@via:/build/netbsd-cur/obj/sys/arch/i386/compile/GENERIC.RE
> [...]
> Realtek Semiconductor 8169SC/8110SC 10/100/1000 Ethernet (ethernet
> network, revision 0x10) at pci0 dev 9 function 0 not configured

FYI, there is a report that EEPROM read function might have
some problem on 8169/8110SC variants.

> After putting a few aprint into dev/ic/rtl8169.c (all within re_attach)
> I noticed the following situation:
> I booted 14 times.
> 3 times it stuck at CSR_WRITE_1(sc, RTK_EECMD, RTK_EEMODE_AUTOLOAD);
> 6 times it stuck at aprint_verbose("%s: using %d tx descriptors\n",
> 		sc->sc_dev.dv_xname, sc->re_ldata.re_tx_desc_cnt);
>   with no output.
> 2 times it stuck between the for (i=0;...) around line 598 and the
>   following break.
> and 3 times ist stuck after one or more DELAY in line 604 which might be
> the same stuck as the one above.
> 
> For me as programming novice it looks like there is a Problem reading
> data from the Card/the Eprom.

Thanks for detailed info. On 8169 chips we use RTK_EEMODE_AUTOLOAD
command, but according to FreeBSD cvs log it was a just workaround
for their old EEPROM read function and they (and OpenBSD) no longer
use it. How about the attached one? (untested though)
---
Izumi Tsutsui


Index: rtl8169.c
===================================================================
RCS file: /cvsroot/src/sys/dev/ic/rtl8169.c,v
retrieving revision 1.76
diff -u -r1.76 rtl8169.c
--- rtl8169.c	26 Dec 2006 13:45:43 -0000	1.76
+++ rtl8169.c	28 Jan 2007 00:13:48 -0000
@@ -574,6 +574,20 @@
 	/* Reset the adapter. */
 	re_reset(sc);
 
+	if (rtk_read_eeprom(sc, RTK_EE_ID, RTK_EEADDR_LEN1) == 0x8129)
+		addr_len = RTK_EEADDR_LEN1;
+	else
+		addr_len = RTK_EEADDR_LEN0;
+
+	/*
+	 * Get station address from the EEPROM.
+	 */
+	for (i = 0; i < 3; i++) {
+		val = rtk_read_eeprom(sc, RTK_EE_EADDR0 + i, addr_len);
+		eaddr[(i * 2) + 0] = val & 0xff;
+		eaddr[(i * 2) + 1] = val >> 8;
+	}
+
 	if (sc->rtk_type == RTK_8169) {
 		uint32_t hwrev;
 
@@ -589,46 +603,11 @@
 			sc->sc_rev = 1;
 
 		/* Set RX length mask */
-
 		sc->re_rxlenmask = RE_RDESC_STAT_GFRAGLEN;
-
-		/* Force station address autoload from the EEPROM */
-
-		CSR_WRITE_1(sc, RTK_EECMD, RTK_EEMODE_AUTOLOAD);
-		for (i = 0; i < RTK_TIMEOUT; i++) {
-			if ((CSR_READ_1(sc, RTK_EECMD) & RTK_EEMODE_AUTOLOAD)
-			    == 0)
-				break;
-			DELAY(100);
-		}
-		if (i == RTK_TIMEOUT)
-			aprint_error("%s: eeprom autoload timed out\n",
-			    sc->sc_dev.dv_xname);
-
-		for (i = 0; i < ETHER_ADDR_LEN; i++)
-			eaddr[i] = CSR_READ_1(sc, RTK_IDR0 + i);
-
 		sc->re_ldata.re_tx_desc_cnt = RE_TX_DESC_CNT_8169;
 	} else {
-
 		/* Set RX length mask */
-
 		sc->re_rxlenmask = RE_RDESC_STAT_FRAGLEN;
-
-		if (rtk_read_eeprom(sc, RTK_EE_ID, RTK_EEADDR_LEN1) == 0x8129)
-			addr_len = RTK_EEADDR_LEN1;
-		else
-			addr_len = RTK_EEADDR_LEN0;
-
-		/*
-		 * Get station address from the EEPROM.
-		 */
-		for (i = 0; i < 3; i++) {
-			val = rtk_read_eeprom(sc, RTK_EE_EADDR0 + i, addr_len);
-			eaddr[(i * 2) + 0] = val & 0xff;
-			eaddr[(i * 2) + 1] = val >> 8;
-		}
-
 		sc->re_ldata.re_tx_desc_cnt = RE_TX_DESC_CNT_8139;
 	}