re0 not working at boot on -CURRENT
Yonghyeon PYUN
pyunyh at gmail.com
Tue Sep 10 02:15:10 UTC 2013
On Fri, Sep 06, 2013 at 10:42:56PM +0200, Guido Falsi wrote:
> On 09/06/13 08:15, Yonghyeon PYUN wrote:
> >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 at 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?
> >
>
> Hi!
>
> Thanks for looking into this and sorry for the delay in reporting back.
>
> Unluckily the patch does not solve nor mitigates the problem. Symptoms
> are very similar.
[...]
> Only real difference is the re_eri_read timeout. It did not output that
> error message before.
Oops, sorry. It seems there is logic error in the diff.
Try attached one again.
-------------- next part --------------
Index: sys/dev/re/if_re.c
===================================================================
--- sys/dev/re/if_re.c (revision 255410)
+++ 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_READY) != 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
@@ -1367,6 +1465,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 +1529,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 255410)
+++ 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,19 @@
#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
+#define RL_ERIAR_READY 0x80000000
+
/*
* The RealTek doesn't use a fragment-based descriptor mechanism.
* Instead, there are only four register sets, each or which represents
@@ -877,6 +892,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;
More information about the freebsd-net
mailing list