Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 6 Sep 2013 15:15:21 +0900
From:      Yonghyeon PYUN <pyunyh@gmail.com>
To:        Guido Falsi <mad@madpilot.net>
Cc:        freebsd-net@freebsd.org
Subject:   Re: re0 not working at boot on -CURRENT
Message-ID:  <20130906061521.GB3070@michelle.cdnetworks.com>
In-Reply-To: <51DD9E15.7070609@madpilot.net>
References:  <51DC726D.6040601@madpilot.net> <20130710070431.GE2753@michelle.cdnetworks.com> <51DD9E15.7070609@madpilot.net>

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

--9amGYk9869ThD9tj
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

On Wed, Jul 10, 2013 at 07:47:01PM +0200, Guido Falsi wrote:
> On 07/10/13 09:04, Yonghyeon PYUN wrote:
> >On Tue, Jul 09, 2013 at 10:28:29PM +0200, Guido Falsi wrote:
> >>Hi,
> >>
> >>I have a PC with an integrate re ethernet interface, pciconf identifies
> >>it like this:
> >>
> >>re0@pci0:3:0:0: class=0x020000 card=0x11c01734 chip=0x816810ec rev=0x07
> >>hdr=0x00
> >>
> >>I'm running FreeBSD current r252261.
> >>
> >>As stated in the subject after boot the interface does not work correctly.
> >>
> >>Using tcpdump on another host I noticed that packets (ICMP echo requests
> >>for example) do get sent, and replies generated by the other host, but
> >>the kernel does not seem to see them. Except that every now and then
> >>some packet does get to the system.
> >>
> >>I'm seeing packet 7, 27, 47, 66, 86, 106, 125, 144, 164, 183 and so on
> >>from a ping which has been running for some time. Just about one every
> >>twenty. Some pattern is showing up.
> >>
> >>this is the output of ifconfig re0 after boot:
> >>
> >>re0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
> >>
> >>options=8209b<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,VLAN_HWCSUM,WOL_MAGIC,LINKSTATE>
> >>         ether 00:19:99:f8:d3:0b
> >>         inet 172.24.42.13 netmask 0xffffff00 broadcast 172.24.42.255
> >>         inet6 fe80::219:99ff:fef8:d30b%re0 prefixlen 64 scopeid 0x2
> >>         nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>
> >>         media: Ethernet autoselect (100baseTX <full-duplex>)
> >>         status: active
> >>
> >>If I just touch any interface flag with ifconfig, anyone, tso, -txcsum
> >>-rxcsum, it starts working flawlessly. It keeps working also if I
> >>perform the opposite operation with ifconfig afterwards, so it is not
> >>the flag itself fixing it.
> >>
> >>This is an ifconfig after performing this exercise(it's the same, since
> >>I disabled txcsum and reactivated it in this instance):
> >>
> >>re0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
> >>
> >>options=8209b<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,VLAN_HWCSUM,WOL_MAGIC,LINKSTATE>
> >>         ether 00:19:99:f8:d3:0b
> >>         inet 172.24.42.13 netmask 0xffffff00 broadcast 172.24.42.255
> >>         inet6 fe80::219:99ff:fef8:d30b%re0 prefixlen 64 scopeid 0x2
> >>         nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>
> >>         media: Ethernet autoselect (100baseTX <full-duplex>)
> >>         status: active
> >>
> >>I don't know much about FreeBSD network drivers so i can't make theories
> >>about this. I hope someone has an idea what the problem could be.
> >>
> >>I'm available for any further information needed, test, experiment and
> >>so on.
> >
> >Could you show me dmesg output(re(4) and rgephy(4) only)?
> 
> re0: <RealTek 8168/8111 B/C/CP/D/DP/E/F PCIe Gigabit Ethernet> port 
> 0xd000-0xd0ff mem 0xf2104000-0xf2104fff,0xf2100000-0xf2103fff irq 17 at 
> device 0.0 on pci3
> re0: Using 1 MSI-X message
> re0: turning off MSI enable bit.
> re0: Chip rev. 0x2c800000
> re0: MAC rev. 0x00000000
> re0: Ethernet address: 00:19:99:f8:d3:0b
> miibus0: <MII bus> on re0
> rgephy0: <RTL8169S/8110S/8211 1000BASE-T media interface> PHY 1 on miibus0
> rgephy0:  none, 10baseT, 10baseT-FDX, 10baseT-FDX-flow, 100baseTX, 
> 100baseTX-FDX, 100baseTX-FDX-flow, 1000baseT, 1000baseT-master, 
> 1000baseT-FDX, 1000baseT-FDX-master, 1000baseT-FDX-flow, 
> 1000baseT-FDX-flow-master, auto, auto-flow
> 
> Also, I'm loading this as a module, but, for as much as I know, this 
> should not make any difference.
> 
> 
> >Did it ever work or you see the issue only on CURRENT?
> 
> Never worked on this machine (I own it since the last days of February).
> 
> I only installed current on it. If needed I can find time to test a 
> recent 9.x snapshot on it.
> 
> I worked around the problem till now using an USB ethernet adapter, 
> always wanted to report this problem, but I've been lazy :)
> 

Would you try attached patch and let me know whether it makes any
difference?


--9amGYk9869ThD9tj
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment; filename="re.eri.diff"

Index: sys/dev/re/if_re.c
===================================================================
--- sys/dev/re/if_re.c	(revision 255289)
+++ sys/dev/re/if_re.c	(working copy)
@@ -289,6 +289,9 @@ static int re_miibus_readreg	(device_t, int, int);
 static int re_miibus_writereg	(device_t, int, int, int);
 static void re_miibus_statchg	(device_t);
 
+static uint32_t re_eri_read	(struct rl_softc *, bus_size_t, int);
+static void re_eri_write	(struct rl_softc *, bus_size_t, uint32_t, int);
+
 static void re_set_jumbo	(struct rl_softc *, int);
 static void re_set_rxmode		(struct rl_softc *);
 static void re_reset		(struct rl_softc *);
@@ -602,6 +605,7 @@ re_miibus_statchg(device_t dev)
 	struct rl_softc		*sc;
 	struct ifnet		*ifp;
 	struct mii_data		*mii;
+	uint32_t		exgmac;
 
 	sc = device_get_softc(dev);
 	mii = device_get_softc(sc->rl_miibus);
@@ -627,14 +631,108 @@ re_miibus_statchg(device_t dev)
 			break;
 		}
 	}
+
+	if ((sc->rl_flags & RL_FLAG_LINK) == 0)
+		return;
+
 	/*
 	 * RealTek controllers does not provide any interface to
 	 * Tx/Rx MACs for resolved speed, duplex and flow-control
 	 * parameters.
 	 */
+
+	switch (sc->rl_hwrev->rl_rev) {
+	case RL_HWREV_8168E_VL:
+		if (sc->rl_icrev == 0x00100000) {
+			switch (IFM_SUBTYPE(mii->mii_media_active)) {
+			case IFM_1000_T:
+				re_eri_write(sc, 0x1BC, 0x00000011,
+				    RL_ERIAR_EXGMAC);
+				re_eri_write(sc, 0x1BC, 0x00000005,
+				    RL_ERIAR_EXGMAC);
+				break;
+			case IFM_100_TX:
+				re_eri_write(sc, 0x1BC, 0x0000001F,
+				    RL_ERIAR_EXGMAC);
+				re_eri_write(sc, 0x1bc, 0x00000005,
+				    RL_ERIAR_EXGMAC);
+				break;
+			default:
+				re_eri_write(sc, 0x1BC, 0x0000001F,
+				    RL_ERIAR_EXGMAC);
+				re_eri_write(sc, 0x1BC, 0x0000003F,
+				    RL_ERIAR_EXGMAC);
+				break;
+			}
+		}
+		exgmac = re_eri_read(sc, 0xDC, RL_ERIAR_EXGMAC);
+		exgmac &= ~0x01;
+		re_eri_write(sc, 0x1BC, exgmac, RL_ERIAR_EXGMAC);
+		exgmac |= 0x01;
+		re_eri_write(sc, 0x1BC, exgmac, RL_ERIAR_EXGMAC);
+		break;
+	case RL_HWREV_8168F:
+	case RL_HWREV_8411:
+		switch (IFM_SUBTYPE(mii->mii_media_active)) {
+		case IFM_1000_T:
+			re_eri_write(sc, 0x1BC, 0x00000011, RL_ERIAR_EXGMAC);
+			re_eri_write(sc, 0x1BC, 0x00000005, RL_ERIAR_EXGMAC);
+			break;
+		default:
+			re_eri_write(sc, 0x1BC, 0x0000001F, RL_ERIAR_EXGMAC);
+			re_eri_write(sc, 0x1BC, 0x0000003F, RL_ERIAR_EXGMAC);
+			break;
+		}
+		break;
+	}
 }
 
+static uint32_t
+re_eri_read(struct rl_softc *sc, bus_size_t addr, int type)
+{
+	int i;
+
+	CSR_WRITE_4(sc, RL_ERIAR, addr | type | RL_ERIAR_BYTES_MASK |
+	    RL_ERIAR_READ);
+	for (i = 100; i > 0; i--) {
+		DELAY(100);
+		if ((CSR_READ_4(sc, RL_ERIAR) & RL_ERIAR_BUSY) == 0)
+			break;
+	}
+	if (i == 0) {
+		device_printf(sc->rl_dev, "%s: timed out\n", __func__);
+		return (0xFFFFFFFF);
+	}
+	return (CSR_READ_4(sc, RL_ERIDR));
+}
+
 /*
+ * ERI is used to access extended GigaMAC register.  addr should be
+ * aligned on 4 bytes boundary. mask(e.g. bit 12~15 of RL_ERIAR) is
+ * used to determine which bytes in RL_ERIDR should be accessed.
+ * Because we have to access 32bits quantity regardless of the value
+ * of mask, make driver access to 4 bytes which in turn means it's
+ * responsibility of caller to preserve unwanted bytes in write
+ * access.
+ */
+static void
+re_eri_write(struct rl_softc *sc, bus_size_t addr, uint32_t val, int type)
+{
+	int i;
+
+	CSR_WRITE_4(sc, RL_ERIDR, val);
+	CSR_WRITE_4(sc, RL_ERIAR, addr | type | RL_ERIAR_BYTES_MASK |
+	    RL_ERIAR_WRITE);
+	for (i = 100; i > 0; i--) {
+		DELAY(100);
+		if ((CSR_READ_4(sc, RL_ERIAR) & RL_ERIAR_BUSY) == 0)
+			break;
+	}
+	if (i == 0)
+		device_printf(sc->rl_dev, "%s: timed out\n", __func__);
+}
+
+/*
  * Set the RX configuration and 64-bit multicast hash filter.
  */
 static void
@@ -1357,6 +1455,7 @@ re_attach(device_t dev)
 			device_printf(dev, "no ASPM capability\n");
 	}
 
+	sc->rl_icrev = 0;
 	hw_rev = re_hwrevs;
 	hwrev = CSR_READ_4(sc, RL_TXCFG);
 	switch (hwrev & 0x70000000) {
@@ -1367,6 +1466,8 @@ re_attach(device_t dev)
 		break;
 	default:
 		device_printf(dev, "Chip rev. 0x%08x\n", hwrev & 0x7c800000);
+		device_printf(dev, "IC rev. 0x%08x\n", hwrev & 0x00700000);
+		sc->rl_icrev = hwrev & 0x00700000;
 		hwrev &= RL_TXCFG_HWREV;
 		break;
 	}
@@ -1429,7 +1530,7 @@ re_attach(device_t dev)
 		sc->rl_flags |= RL_FLAG_MACSLEEP;
 		/* FALLTHROUGH */
 	case RL_HWREV_8168C:
-		if ((hwrev & 0x00700000) == 0x00200000)
+		if (sc->rl_icrev == 0x00200000)
 			sc->rl_flags |= RL_FLAG_MACSLEEP;
 		/* FALLTHROUGH */
 	case RL_HWREV_8168CP:
Index: sys/pci/if_rlreg.h
===================================================================
--- sys/pci/if_rlreg.h	(revision 255289)
+++ sys/pci/if_rlreg.h	(working copy)
@@ -143,6 +143,8 @@
 #define	RL_MACDBG		0x006D	/* 8 bits, 8168C SPIN2 only */
 #define	RL_GPIO			0x006E	/* 8 bits, 8168C SPIN2 only */
 #define	RL_PMCH			0x006F	/* 8 bits */
+#define	RL_ERIDR		0x0070
+#define	RL_ERIAR		0x0074
 #define	RL_MAXRXPKTLEN		0x00DA	/* 16 bits, chip multiplies by 8 */
 #define	RL_INTRMOD		0x00E2	/* 16 bits */
 
@@ -540,6 +542,18 @@
 #define	RL_GMEDIASTAT_TXFLOW	0x40	/* TX flow control on */
 #define	RL_GMEDIASTAT_TBI	0x80	/* TBI enabled */
 
+#define	RL_ERIAR_BYTES_1ST	0x00001000	
+#define	RL_ERIAR_BYTES_2ND	0x00002000	
+#define	RL_ERIAR_BYTES_3RD	0x00004000	
+#define	RL_ERIAR_BYTES_4TH	0x00008000	
+#define	RL_ERIAR_BYTES_MASK	0x0000F000	
+#define	RL_ERIAR_EXGMAC		0x00000000
+#define	RL_ERIAR_MSIX		0x00010000
+#define	RL_ERIAR_ASF		0x00020000
+#define	RL_ERIAR_READ		0x00000000
+#define	RL_ERIAR_WRITE		0x80000000
+#define	RL_ERIAR_BUSY		0x80000000
+
 /*
  * The RealTek doesn't use a fragment-based descriptor mechanism.
  * Instead, there are only four register sets, each or which represents
@@ -877,6 +891,7 @@ struct rl_softc {
 	bus_dma_tag_t		rl_parent_tag;
 	uint8_t			rl_type;
 	const struct rl_hwrev	*rl_hwrev;
+	uint32_t		rl_icrev;
 	int			rl_eecmd_read;
 	int			rl_eewidth;
 	int			rl_expcap;

--9amGYk9869ThD9tj--



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