Skip to contentSkip to conversation

r8169 mac reading/writing broken

PATCH Applied Timo Teräs 5 participants 22 messages Mar 27, 2010 – Mar 31, 2010

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

It seems that my r8169 mac address is lost when r8169 module is reloaded, or system is soft rebooted. Hard power reset recovers the mac address again. The commit cc098dc705895f6b0109b7e8e026ac2b8ae1c0a1 (r8169: restore mac addr in rtl8169_remove_one and rtl_shutdown) seems to have broken it. The first four bytes of mac address go zeroes because of this.

I did some more testing, and added debugging info to rtl_rar_set(). It would appear that even if I write any mac address (with ifconfig) and reread the MAC0..MAC5 register, the first four bytes get zeroed. So it would sounds like the hardware is faulty, or that the rtl_rar_set function is buggy.

Any suggestions to fix this?

The hardware in question is a 3-in-1 NIC. Each three PCI devices shows up as something like:

00:09.0 Ethernet controller [0200]: Realtek Semiconductor Co., Ltd. RTL-8110SC/8169SC Gigabit Ethernet [10ec:8167] (rev 10)
Subsystem: Jetway Information Co., Ltd. Device [16f3:10ec]
Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV+ VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx-
Status: Cap+ 66MHz+ UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
Latency: 64 (8000ns min, 16000ns max), Cache Line Size: 32 bytes
Interrupt: pin A routed to IRQ 18
Region 0: I/O ports at f200 [size=256]
Region 1: Memory at fdfff000 (32-bit, non-prefetchable) [size=256]
[virtual] Expansion ROM at 3c000000 [disabled] [size=128K]
Capabilities: [dc] Power Management version 2
Flags: PMEClk- DSI- D1+ D2+ AuxCurrent=375mA PME(D0-,D1+,D2+,D3hot+,D3cold+)
Status: D0 NoSoftRst- PME-Enable- DSel=0 DScale=0 PME-
Kernel driver in use: r8169

And the kernel drivers prints the following at startup:

r8169 Gigabit Ethernet driver 2.3LK-NAPI loaded
r8169 0000:00:09.0: PCI->APIC IRQ transform: INT A -> IRQ 18 r8169 0000:00:09.0: no PCI Express capability
eth0: RTL8169sc/8110sc at 0xf81ae000, 00:30:18:a6:2b:6c, XID 18000000 IRQ 18 r8169 Gigabit Ethernet driver 2.3LK-NAPI loaded
r8169 0000:00:0b.0: PCI->APIC IRQ transform: INT A -> IRQ 19 r8169 0000:00:0b.0: no PCI Express capability
eth1: RTL8169sc/8110sc at 0xf81b2000, 00:30:18:a6:2b:6d, XID 18000000 IRQ 19 r8169 Gigabit Ethernet driver 2.3LK-NAPI loaded
r8169 0000:00:0c.0: PCI->APIC IRQ transform: INT A -> IRQ 16 r8169 0000:00:0c.0: no PCI Express capability
eth2: RTL8169sc/8110sc at 0xf81b6000, 00:30:18:a6:2b:6e, XID 18000000 IRQ 16

- Timo

#1 lore raw

Timo Teräs <[email protected]> :
[...]

Quoted 6 lines

I did some more testing, and added debugging info to rtl_rar_set(). It would appear that even if I write any mac address (with ifconfig) and reread the MAC0..MAC5 register, the first four bytes get zeroed. So it would sounds like the hardware is faulty, or that the rtl_rar_set function is buggy.

Any suggestions to fix this ?

Try something like the patch below and please send a complete lspci -vvv.

I wonder what the bus controler looks like.

drivers/net/r8169.c +12 -1
index 9d3ebf3..5db357a 100644
@@ -2814,6 +2814,7 @@ static void rtl_rar_set(struct rtl8169_private *tp, u8 *addr)
 	void __iomem *ioaddr = tp->mmio_addr;
 	u32 high;
 	u32 low;
+	int i;
 
 	low  = addr[0] | (addr[1] << 8) | (addr[2] << 16) | (addr[3] << 24);
 	high = addr[4] | (addr[5] << 8);
@@ -2822,7 +2823,17 @@ static void rtl_rar_set(struct rtl8169_private *tp, u8 *addr)
 
 	RTL_W8(Cfg9346, Cfg9346_Unlock);
 	RTL_W32(MAC0, low);
-	RTL_W32(MAC4, high);
+	for (i = 0; i < 16; i++) {
+		u32 read;
+
+		RTL_W32(MAC4, high);
+		read = RTL_R32(MAC4);
+		if (read != high) {
+			printk(KERN_ERR PFX
+			       "failure %02d: read = 0x%08x, write = 0x%08x\n",
+				i, read, high);
+		}
+	}
 	RTL_W8(Cfg9346, Cfg9346_Lock);
 
 	spin_unlock_irq(&tp->lock);
#2 lore raw
Quoted 10 lines · François Romieu

Timo Teräs <[email protected]> :
[...]

Quoted 6 lines

I did some more testing, and added debugging info to rtl_rar_set(). It would appear that even if I write any mac address (with ifconfig) and reread the MAC0..MAC5 register, the first four bytes get zeroed. So it would sounds like the hardware is faulty, or that the rtl_rar_set function is buggy.

Any suggestions to fix this ?

Try something like the patch below and please send a complete lspci -vvv.

Attached at the end.

Quoted 23 lines

I wonder what the bus controler looks like.

drivers/net/r8169.c +5 -1
index 9d3ebf3..5db357a 100644
@@ -2814,6 +2814,7 @@ static void rtl_rar_set(struct rtl8169_private *tp, u8 *addr)
 	void __iomem *ioaddr = tp->mmio_addr;
 	u32 high;
 	u32 low;
+	int i;
 
 	low  = addr[0] | (addr[1] << 8) | (addr[2] << 16) | (addr[3] << 24);
 	high = addr[4] | (addr[5] << 8);
@@ -2822,7 +2823,17 @@ static void rtl_rar_set(struct rtl8169_private *tp, u8 *addr)
 
 	RTL_W8(Cfg9346, Cfg9346_Unlock);
 	RTL_W32(MAC0, low);
-	RTL_W32(MAC4, high);
+	for (i = 0; i < 16; i++) {
+		u32 read;
+
+		RTL_W32(MAC4, high);

drivers/net/r8169.c static void rtl_rar_set(struct rtl8169_private *tp, u8 *addr) · line 2839

Quoted 10 lines
drivers/net/r8169.c +7 -0
+		read = RTL_R32(MAC4);
+		if (read != high) {
+			printk(KERN_ERR PFX
+			       "failure %02d: read = 0x%08x, write = 0x%08x\n",
+				i, read, high);
+		}
+	}
 	RTL_W8(Cfg9346, Cfg9346_Lock);
 
 	spin_unlock_irq(&tp->lock);

I don't think this would do anything. The high part is recorded correctly always. It's the 'low' part that gets discarded. I can do similar test if writing it more times will help. Will post results soon.

- Timo

00:00.0 Host bridge: VIA Technologies, Inc. CN700/VN800/P4M800CE/Pro Host Bridge
Subsystem: VIA Technologies, Inc. CN700/VN800/P4M800CE/Pro Host Bridge
Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx-
Status: Cap+ 66MHz+ UDF- FastB2B- ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort+ >SERR- <PERR+ INTx-
Latency: 8
Region 0: Memory at e8000000 (32-bit, prefetchable) [size=128M]
Capabilities: [80] AGP version 3.5
Status: RQ=8 Iso- ArqSz=0 Cal=0 SBA+ ITACoh- GART64- HTrans- 64bit- FW+ AGP3+ Rate=x4,x8
Command: RQ=1 ArqSz=0 Cal=0 SBA- AGP- GART64- 64bit- FW- Rate=<none>
Capabilities: [50] Power Management version 2
Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0-,D1-,D2-,D3hot-,D3cold-)
Status: D0 NoSoftRst- PME-Enable- DSel=0 DScale=0 PME-
Kernel driver in use: agpgart-via

00:00.1 Host bridge: VIA Technologies, Inc. CN700/VN800/P4M800CE/Pro Host Bridge
Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx-
Status: Cap- 66MHz- UDF- FastB2B- ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
Latency: 0

00:00.2 Host bridge: VIA Technologies, Inc. CN700/VN800/P4M800CE/Pro Host Bridge
Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx-
Status: Cap- 66MHz- UDF- FastB2B- ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
Latency: 0

00:00.3 Host bridge: VIA Technologies, Inc. PT890 Host Bridge
Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx-
Status: Cap- 66MHz- UDF- FastB2B- ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
Latency: 0

00:00.4 Host bridge: VIA Technologies, Inc. CN700/VN800/P4M800CE/Pro Host Bridge
Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx-
Status: Cap- 66MHz- UDF- FastB2B- ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
Latency: 0

00:00.7 Host bridge: VIA Technologies, Inc. CN700/VN800/P4M800CE/Pro Host Bridge
Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx-
Status: Cap- 66MHz- UDF- FastB2B- ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
Latency: 0

00:01.0 PCI bridge: VIA Technologies, Inc. VT8237/VX700 PCI Bridge (prog-if 00 [Normal decode])
Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx-
Status: Cap+ 66MHz+ UDF- FastB2B- ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
Latency: 0
Bus: primary=00, secondary=01, subordinate=01, sec-latency=0
I/O behind bridge: 0000d000-0000dfff
Memory behind bridge: fb000000-fcffffff
Prefetchable memory behind bridge: f4000000-f7ffffff
Secondary status: 66MHz+ FastB2B- ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort+ <SERR+ <PERR+
BridgeCtl: Parity- SERR- NoISA- VGA+ MAbort- >Reset- FastB2B-
PriDiscTmr- SecDiscTmr- DiscTmrStat- DiscTmrSERREn-
Capabilities: [70] Power Management version 2
Flags: PMEClk- DSI- D1+ D2- AuxCurrent=0mA PME(D0-,D1-,D2-,D3hot-,D3cold-)
Status: D0 NoSoftRst- PME-Enable- DSel=0 DScale=0 PME-

00:09.0 Ethernet controller: Realtek Semiconductor Co., Ltd. RTL-8110SC/8169SC Gigabit Ethernet (rev 10)
Subsystem: Jetway Information Co., Ltd. Device 10ec
Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV+ VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx-
Status: Cap+ 66MHz+ UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
Latency: 64 (8000ns min, 16000ns max), Cache Line Size: 32 bytes
Interrupt: pin A routed to IRQ 18
Region 0: I/O ports at f200 [size=256]
Region 1: Memory at fdfff000 (32-bit, non-prefetchable) [size=256]
[virtual] Expansion ROM at 3c000000 [disabled] [size=128K]
Capabilities: [dc] Power Management version 2
Flags: PMEClk- DSI- D1+ D2+ AuxCurrent=375mA PME(D0-,D1+,D2+,D3hot+,D3cold+)
Status: D0 NoSoftRst- PME-Enable- DSel=0 DScale=0 PME-
Kernel driver in use: r8169

00:0a.0 FireWire (IEEE 1394): VIA Technologies, Inc. VT6306 Fire II IEEE 1394 OHCI Link Layer Controller (rev 80) (prog-if 10 [OHCI])
Subsystem: VIA Technologies, Inc. VT6306 Fire II IEEE 1394 OHCI Link Layer Controller
Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping+ SERR- FastB2B- DisINTx-
Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
Latency: 32 (8000ns max), Cache Line Size: 64 bytes
Interrupt: pin A routed to IRQ 19
Region 0: Memory at fdffe000 (32-bit, non-prefetchable) [size=2K]
Region 1: I/O ports at ff00 [size=128]
Capabilities: [50] Power Management version 2
Flags: PMEClk- DSI- D1- D2+ AuxCurrent=0mA PME(D0-,D1-,D2+,D3hot+,D3cold+)
Status: D0 NoSoftRst- PME-Enable- DSel=0 DScale=0 PME-
Kernel driver in use: firewire_ohci

00:0b.0 Ethernet controller: Realtek Semiconductor Co., Ltd. RTL-8110SC/8169SC Gigabit Ethernet (rev 10)
Subsystem: Jetway Information Co., Ltd. Device 10ec
Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV+ VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx-
Status: Cap+ 66MHz+ UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
Latency: 64 (8000ns min, 16000ns max), Cache Line Size: 32 bytes
Interrupt: pin A routed to IRQ 19
Region 0: I/O ports at f000 [size=256]
Region 1: Memory at fdffd000 (32-bit, non-prefetchable) [size=256]
[virtual] Expansion ROM at 3c020000 [disabled] [size=128K]
Capabilities: [dc] Power Management version 2
Flags: PMEClk- DSI- D1+ D2+ AuxCurrent=375mA PME(D0-,D1+,D2+,D3hot+,D3cold+)
Status: D0 NoSoftRst- PME-Enable- DSel=0 DScale=0 PME-
Kernel driver in use: r8169

00:0c.0 Ethernet controller: Realtek Semiconductor Co., Ltd. RTL-8110SC/8169SC Gigabit Ethernet (rev 10)
Subsystem: Jetway Information Co., Ltd. Device 10ec
Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV+ VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx-
Status: Cap+ 66MHz+ UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
Latency: 64 (8000ns min, 16000ns max), Cache Line Size: 32 bytes
Interrupt: pin A routed to IRQ 16
Region 0: I/O ports at ec00 [size=256]
Region 1: Memory at fdffc000 (32-bit, non-prefetchable) [size=256]
[virtual] Expansion ROM at 3c040000 [disabled] [size=128K]
Capabilities: [dc] Power Management version 2
Flags: PMEClk- DSI- D1+ D2+ AuxCurrent=375mA PME(D0-,D1+,D2+,D3hot+,D3cold+)
Status: D0 NoSoftRst- PME-Enable- DSel=0 DScale=0 PME-
Kernel driver in use: r8169

00:0f.0 IDE interface: VIA Technologies, Inc. VIA VT6420 SATA RAID Controller (rev 80) (prog-if 8f [Master SecP SecO PriP PriO])
Subsystem: VIA Technologies, Inc. VIA VT6420 SATA RAID Controller
Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx-
Status: Cap+ 66MHz- UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
Latency: 32
Interrupt: pin B routed to IRQ 20
Region 0: I/O ports at fe00 [size=8]
Region 1: I/O ports at fd00 [size=4]
Region 2: I/O ports at fc00 [size=8]
Region 3: I/O ports at fb00 [size=4]
Region 4: I/O ports at fa00 [size=16]
Region 5: I/O ports at ee00 [size=256]
Capabilities: [c0] Power Management version 2
Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0-,D1-,D2-,D3hot-,D3cold-)
Status: D0 NoSoftRst- PME-Enable- DSel=0 DScale=0 PME-
Kernel driver in use: sata_via

00:0f.1 IDE interface: VIA Technologies, Inc. VT82C586A/B/VT82C686/A/B/VT823x/A/C PIPC Bus Master IDE (rev 06) (prog-if 8a [Master SecP PriP])

	Subsystem: VIA Technologies, Inc. VT82C586/B/VT82C686/A/B/VT8233/A/C/VT8235 PIPC Bus Master IDE
	Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx-
	Status: Cap+ 66MHz- UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
	Latency: 32
	Interrupt: pin A routed to IRQ 20
	Region 0: [virtual] Memory at 000001f0 (32-bit, non-prefetchable) [size=8]
	Region 1: [virtual] Memory at 000003f0 (type 3, non-prefetchable) [size=1]
	Region 2: [virtual] Memory at 00000170 (32-bit, non-prefetchable) [size=8]
	Region 3: [virtual] Memory at 00000370 (type 3, non-prefetchable) [size=1]
	Region 4: I/O ports at f900 [size=16]
	Capabilities: [c0] Power Management version 2
		Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0-,D1-,D2-,D3hot-,D3cold-)
		Status: D0 NoSoftRst- PME-Enable- DSel=0 DScale=0 PME-
	Kernel driver in use: pata_via

00:10.0 USB Controller: VIA Technologies, Inc. VT82xxxxx UHCI USB 1.1 Controller (rev 81) (prog-if 00 [UHCI])
Subsystem: VIA Technologies, Inc. VT82xxxxx UHCI USB 1.1 Controller
Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx-
Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
Latency: 32, Cache Line Size: 64 bytes
Interrupt: pin A routed to IRQ 21
Region 4: I/O ports at f800 [size=32]
Capabilities: [80] Power Management version 2
Flags: PMEClk- DSI- D1+ D2+ AuxCurrent=375mA PME(D0+,D1+,D2+,D3hot+,D3cold+)
Status: D0 NoSoftRst- PME-Enable- DSel=0 DScale=0 PME-
Kernel driver in use: uhci_hcd

00:10.1 USB Controller: VIA Technologies, Inc. VT82xxxxx UHCI USB 1.1 Controller (rev 81) (prog-if 00 [UHCI])
Subsystem: VIA Technologies, Inc. VT82xxxxx UHCI USB 1.1 Controller
Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx-
Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
Latency: 32, Cache Line Size: 64 bytes
Interrupt: pin A routed to IRQ 21
Region 4: I/O ports at f700 [size=32]
Capabilities: [80] Power Management version 2
Flags: PMEClk- DSI- D1+ D2+ AuxCurrent=375mA PME(D0+,D1+,D2+,D3hot+,D3cold+)
Status: D0 NoSoftRst- PME-Enable- DSel=0 DScale=0 PME-
Kernel driver in use: uhci_hcd

00:10.2 USB Controller: VIA Technologies, Inc. VT82xxxxx UHCI USB 1.1 Controller (rev 81) (prog-if 00 [UHCI])
Subsystem: VIA Technologies, Inc. VT82xxxxx UHCI USB 1.1 Controller
Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx-
Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
Latency: 32, Cache Line Size: 64 bytes
Interrupt: pin B routed to IRQ 21
Region 4: I/O ports at f600 [size=32]
Capabilities: [80] Power Management version 2
Flags: PMEClk- DSI- D1+ D2+ AuxCurrent=375mA PME(D0+,D1+,D2+,D3hot+,D3cold+)
Status: D0 NoSoftRst- PME-Enable- DSel=0 DScale=0 PME-
Kernel driver in use: uhci_hcd

00:10.3 USB Controller: VIA Technologies, Inc. VT82xxxxx UHCI USB 1.1 Controller (rev 81) (prog-if 00 [UHCI])
Subsystem: VIA Technologies, Inc. VT82xxxxx UHCI USB 1.1 Controller
Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx-
Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
Latency: 32, Cache Line Size: 64 bytes
Interrupt: pin B routed to IRQ 21
Region 4: I/O ports at f500 [size=32]
Capabilities: [80] Power Management version 2
Flags: PMEClk- DSI- D1+ D2+ AuxCurrent=375mA PME(D0+,D1+,D2+,D3hot+,D3cold+)
Status: D0 NoSoftRst- PME-Enable- DSel=0 DScale=0 PME-
Kernel driver in use: uhci_hcd

00:10.4 USB Controller: VIA Technologies, Inc. USB 2.0 (rev 86) (prog-if 20 [EHCI])
Subsystem: VIA Technologies, Inc. USB 2.0
Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV+ VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx-
Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
Latency: 32, Cache Line Size: 64 bytes
Interrupt: pin C routed to IRQ 21
Region 0: Memory at fdffb000 (32-bit, non-prefetchable) [size=256]
Capabilities: [80] Power Management version 2
Flags: PMEClk- DSI- D1+ D2+ AuxCurrent=375mA PME(D0+,D1+,D2+,D3hot+,D3cold+)
Status: D0 NoSoftRst- PME-Enable- DSel=0 DScale=0 PME-
Kernel driver in use: ehci_hcd

00:11.0 ISA bridge: VIA Technologies, Inc. VT8237 ISA bridge [KT600/K8T800/K8T890 South]
Subsystem: VIA Technologies, Inc. DFI KT600-AL / Soltek SL-B9D-FGR Motherboard
Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping+ SERR- FastB2B- DisINTx-
Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
Latency: 0
Capabilities: [c0] Power Management version 2
Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0-,D1-,D2-,D3hot-,D3cold-)
Status: D0 NoSoftRst- PME-Enable- DSel=0 DScale=0 PME-

00:11.5 Multimedia audio controller: VIA Technologies, Inc. VT8233/A/8235/8237 AC97 Audio Controller (rev 60)
Subsystem: Jetway Information Co., Ltd. Device 4170
Control: I/O+ Mem- BusMaster- SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx-
Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
Interrupt: pin C routed to IRQ 22
Region 0: I/O ports at ea00 [size=256]
Capabilities: [c0] Power Management version 2
Flags: PMEClk- DSI- D1+ D2+ AuxCurrent=0mA PME(D0-,D1-,D2-,D3hot-,D3cold-)
Status: D0 NoSoftRst- PME-Enable- DSel=0 DScale=0 PME-
Kernel driver in use: VIA 82xx Audio

00:12.0 Ethernet controller: VIA Technologies, Inc. VT6102 [Rhine-II] (rev 78)
Subsystem: VIA Technologies, Inc. VT6102 [Rhine II] Embeded Ethernet Controller on VT8235
Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping+ SERR- FastB2B- DisINTx-
Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
Latency: 32 (750ns min, 2000ns max), Cache Line Size: 64 bytes
Interrupt: pin A routed to IRQ 23
Region 0: I/O ports at e800 [size=256]
Region 1: Memory at fdffa000 (32-bit, non-prefetchable) [size=256]
Capabilities: [40] Power Management version 2
Flags: PMEClk- DSI- D1+ D2+ AuxCurrent=0mA PME(D0+,D1+,D2+,D3hot+,D3cold+)
Status: D0 NoSoftRst- PME-Enable- DSel=0 DScale=0 PME-
Kernel driver in use: via-rhine

01:00.0 VGA compatible controller: VIA Technologies, Inc. CN700/P4M800 Pro/P4M800 CE/VN800 [S3 UniChrome Pro] (rev 01) (prog-if 00 [VGA controller])

	Subsystem: VIA Technologies, Inc. CN700/P4M800 Pro/P4M800 CE/VN800 [S3 UniChrome Pro]
	Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx-
	Status: Cap+ 66MHz+ UDF- FastB2B- ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
	Latency: 32 (500ns min)
	Interrupt: pin A routed to IRQ 5
	Region 0: Memory at f4000000 (32-bit, prefetchable) [size=64M]
	Region 1: Memory at fb000000 (32-bit, non-prefetchable) [size=16M]
	[virtual] Expansion ROM at fc000000 [disabled] [size=64K]
	Capabilities: [60] Power Management version 2
		Flags: PMEClk- DSI+ D1+ D2+ AuxCurrent=0mA PME(D0-,D1-,D2-,D3hot-,D3cold-)
		Status: D0 NoSoftRst- PME-Enable- DSel=0 DScale=0 PME-
	Capabilities: [70] AGP version 3.0
		Status: RQ=256 Iso- ArqSz=0 Cal=7 SBA+ ITACoh- GART64- HTrans- 64bit- FW- AGP3+ Rate=x4,x8
		Command: RQ=1 ArqSz=0 Cal=0 SBA+ AGP- GART64- 64bit- FW- Rate=<none>
#3 lore raw

Timo Teräs <[email protected]> :
[...]

Quoted 3 lines

I don't think this would do anything. The high part is recorded correctly always. It's the 'low' part that gets discarded. I can do similar test if writing it more times will help. Will post results soon.

You may check whether writing MAC4 before MAC0 makes a difference or not as well.

Signature · 1 line
Ueimor
#4 lore raw
Quoted 8 lines · François Romieu

Timo Teräs <[email protected]> :
[...]

Quoted 3 lines

I don't think this would do anything. The high part is recorded correctly always. It's the 'low' part that gets discarded. I can do similar test if writing it more times will help. Will post results soon.

You may check whether writing MAC4 before MAC0 makes a difference or not as well.

It seems that adding single printk between writing MAC0 and MAC4 fixes it. I guess it needs a bit of delay between the writes or something.

#5 lore raw
Quoted 7 lines · Timo Teräs
Quoted 6 lines · François Romieu

Timo Teräs <[email protected]> :
[...]

Quoted 3 lines

I don't think this would do anything. The high part is recorded correctly always. It's the 'low' part that gets discarded. I can do similar test if writing it more times will help. Will post results soon.

Quoted 5 lines
Quoted 2 lines

You may check whether writing MAC4 before MAC0 makes a difference or not as well.

It seems that adding single printk between writing MAC0 and MAC4 fixes it. I guess it needs a bit of delay between the writes or something.

Oh, and writing MAC4 first seems to fix it too.

- Timo

#6 lore raw
In reply to Timo Teräs

Timo Teräs <[email protected]> :
[...]

Quoted 2 lines

It seems that adding single printk between writing MAC0 and MAC4 fixes it. I guess it needs a bit of delay between the writes or something.

Can you test with a single RTL_R32 after each MACx write ?

Signature · 1 line
Ueimor
#7 lore raw
Quoted 6 lines · François Romieu

Timo Teräs <[email protected]> :
[...]

Quoted 2 lines

It seems that adding single printk between writing MAC0 and MAC4 fixes it. I guess it needs a bit of delay between the writes or something.

Can you test with a single RTL_R32 after each MACx write ?

Adding reading back of the written value fixes it too. Though, disassembly says that it added an extra instructions also (needs to load the 'high' from stack before writing it) so the added delay is probably slightly more than just the io read.

#8 lore raw
Quoted 6 lines · Timo Teräs
Quoted 5 lines · François Romieu

Timo Teräs <[email protected]> :
[...]

Quoted 2 lines

It seems that adding single printk between writing MAC0 and MAC4 fixes it. I guess it needs a bit of delay between the writes or something.

Quoted 6 lines
Quoted 1 line

Can you test with a single RTL_R32 after each MACx write ?

Adding reading back of the written value fixes it too. Though, disassembly says that it added an extra instructions also (needs to load the 'high' from stack before writing it) so the added delay is probably slightly more than just the io read.

I'm not too familiar with PCI details, but this smells a bit like that write-combining is happening and the NIC does not like that.

Any ideas how to check this?

The system experiencing this is a "VIA Eden 1.2Ghz" box.

Or is swapping MAC0/MAC4 writes, or adding the extra read an acceptable fix/workaround?

- Timo

#9 lore raw

Timo Teräs <[email protected]> :
[...]

Quoted 1 line

Any ideas how to check this?

Check the datasheet of VIA's chipset for a WC control bit - there ought to be one - and disable it.

Quoted 2 lines

Or is swapping MAC0/MAC4 writes, or adding the extra read an acceptable fix/workaround?

swapping should reliably disable WC. It would be fine.

Signature · 1 line
Ueimor
#10 lore raw
Quoted 11 lines · François Romieu

Timo Teräs <[email protected]> :
[...]

Quoted 1 line

Any ideas how to check this?

Check the datasheet of VIA's chipset for a WC control bit - there ought to be one - and disable it.

Quoted 2 lines

Or is swapping MAC0/MAC4 writes, or adding the extra read an acceptable fix/workaround?

swapping should reliably disable WC. It would be fine.

This bug was also reported by a Debian user in
<http://bugs.debian.org/573007>, also using a VIA chipset.

This sort of behaviour has been seen before with 64-bit registers written in two 32-bit chunks, on some ARM platforms. You worked around that for the descriptor pointers with:

ommit b39fe41f481d20c201012e4483e76c203802dda7

Author: Francois Romieu <[email protected]>
Date:   Mon Sep 11 20:10:58 2006 +0200

r8169: quirk for the 8110sb on arm platform

A similar problem seems to afflict the multicast hash register on this platform - see <http://bugs.debian.org/407217>, and sorry I didn't report this earlier when I got confirmation of my hypothesis.

I wonder whether there are special rules that need to be followed for updating such registers and which the driver is not following, or a more general bug in the Realtek chips that should be consistently worked-around for all 64-bit registers.

Ben.

Signature · 2 lines
Ben Hutchings
Once a job is fouled up, anything done to improve it makes it worse.
maintainer
#11 lore raw

From: Ben Hutchings <[email protected]>
Date: Sat, 27 Mar 2010 23:20:54 +0000

Quoted 4 lines

I wonder whether there are special rules that need to be followed for updating such registers and which the driver is not following, or a more general bug in the Realtek chips that should be consistently worked-around for all 64-bit registers.

I suspect that MMIO to 64-bit registers in 32-bit chunks is not reliable with these parts, given all of the information we have so far.

#12 lore raw

PATCH 1/1 r8169: fix broken register writes

This is quite similar to b39fe41f481d20c201012e4483e76c203802dda7 though said registers are not even documented as 64-bit registers
- as opposed to the initial TxDescStartAddress ones - but as single bytes which must be combined into 32 bits at the MMIO read/write level before being merged into a 64 bit logical entity.

Credits go to Ben Hutchings <[email protected]> for the MAR registers (aka "multicast is broken for ages on ARM) and to Timo Teräs <[email protected]> for the MAC registers.

---
 drivers/net/r8169.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)
drivers/net/r8169.c +2 -2
index 9d3ebf3..966407c 100644
@@ -2821,8 +2821,8 @@ static void rtl_rar_set(struct rtl8169_private *tp, u8 *addr)
 	spin_lock_irq(&tp->lock);
 
 	RTL_W8(Cfg9346, Cfg9346_Unlock);
-	RTL_W32(MAC0, low);
 	RTL_W32(MAC4, high);
+	RTL_W32(MAC0, low);
 	RTL_W8(Cfg9346, Cfg9346_Lock);
 
 	spin_unlock_irq(&tp->lock);
@@ -4754,8 +4754,8 @@ static void rtl_set_rx_mode(struct net_device *dev)
 		mc_filter[1] = swab32(data);
 	}
 
-	RTL_W32(MAR0 + 0, mc_filter[0]);
 	RTL_W32(MAR0 + 4, mc_filter[1]);
+	RTL_W32(MAR0 + 0, mc_filter[0]);
 
 	RTL_W32(RxConfig, tmp);
 
Signature · 1 line
1.6.6.1
#13 lore raw

Re: [PATCH] r8169: fix broken register writes

Quoted 5 lines · François Romieu

This is quite similar to b39fe41f481d20c201012e4483e76c203802dda7 though said registers are not even documented as 64-bit registers
- as opposed to the initial TxDescStartAddress ones - but as single bytes which must be combined into 32 bits at the MMIO read/write level before being merged into a 64 bit logical entity.

[...]

Thanks François. Which hardware have you tested this on so far? I was hesitant to make changes because of the huge number of variants.

Ben.

Signature · 2 lines
Ben Hutchings
Once a job is fouled up, anything done to improve it makes it worse.
maintainer Applied
#20 lore raw

Re: [PATCH] r8169: fix broken register writes

In reply to François Romieu

From: François Romieu <[email protected]>
Date: Sun, 28 Mar 2010 01:31:43 +0100

Quoted 11 lines

This is quite similar to b39fe41f481d20c201012e4483e76c203802dda7 though said registers are not even documented as 64-bit registers
- as opposed to the initial TxDescStartAddress ones - but as single bytes which must be combined into 32 bits at the MMIO read/write level before being merged into a 64 bit logical entity.

Credits go to Ben Hutchings <[email protected]> for the MAR registers (aka "multicast is broken for ages on ARM) and to Timo Teräs <[email protected]> for the MAC registers.

Applied, thanks Francois.

Probably the rest of the driver should be audited for other areas where we may end up having this problem.

Or, we should create readq/writeq macros (like other drivers do on 32-bit platforms, f.e. see drivers/net/niu.c) which write the two 32-bit parts in this required order. Then access the registers using readq/writeq entities throughout the driver.

This would have two benefits:

1) Coverage for all possible bug cases.

2) Real 64-bit accesses on 64-bit platforms.

Just some suggestions.

Thanks.

#14 lore raw

Re: [PATCH] r8169: fix broken register writes

In reply to Ben Hutchings

Ben Hutchings <[email protected]> :
[...]

Quoted 1 line

Thanks François. Which hardware have you tested this on so far ?

10ec:8169 (rev 10) / RTL8169sb/8110sb / XID 10000000

Timo's is a 10ec:8167 / RTL8169sc/8110sc / XID 18000000. He only tested the MAC[04] part.

Old stuff.

Quoted 1 line

I was hesitant to make changes because of the huge number of variants.

Things will be amended if they break and reverted if they get out of control.

Signature · 1 line
Ueimor
#21 lore raw

Re: [PATCH] r8169: fix broken register writes

In reply to David Miller

David Miller <[email protected]> :
[...]

Quoted 2 lines

Probably the rest of the driver should be audited for other areas where we may end up having this problem.

Those look safe
- MAC0
- MAC4
- MAR0
- CounterAddrLow
- CounterAddrHigh
- TxDescStartAddrLow
- TxDescStartAddrHigh
- RxDescAddrLow
- RxDescAddrHigh

The other candidates are not used yet.

[...]

Quoted 3 lines

1) Coverage for all possible bug cases.

2) Real 64-bit accesses on 64-bit platforms.

I see your point but the MACx and MARx registers are nowhere documented as 64 bit : MAC0 and MAC4 (0x00 to 0x07) span IDR[0..5] + two reserved bytes while MARx are documented as MAR[7..0] (0x08 to 0x0f). It would be nice if it happened to work though.

Signature · 1 line
Ueimor
#15 lore raw

Re: [PATCH] r8169: fix broken register writes

In reply to François Romieu
Quoted 8 lines · Fran?ois Romieu

Ben Hutchings <[email protected]> :
[...]

Quoted 1 line

Thanks Fran?ois. Which hardware have you tested this on so far ?

10ec:8169 (rev 10) / RTL8169sb/8110sb / XID 10000000

Timo's is a 10ec:8167 / RTL8169sc/8110sc / XID 18000000. He only tested the MAC[04] part.

FWIW, XID18000000 here (J7F4) loses MAC4 on shutdown; hadn't tested the patch yet. 2.6.26 (on that box) and 2.6.31 (on identical mb) work, 2.6.33 doesn't. I suspect that bisect would lead to commit cc098dc70 (i.e. the place where we started to set address on shutdown). One more data point: ifconfig hw ether done under 2.6.26 did restore the address. And that's the same function, isn't it?

Another interesting bit: unlike the older kernel, grep for eth0 in .33 dmesg

eth0: RTL8169sc/8110sc at 0xf87fc000, 00:30:18:a4:65:89, XID 18000000 IRQ 18
r8169: eth0: link down
ADDRCONF(NETDEV_UP): eth0: link is not ready
r8169: eth0: link up
ADDRCONF(NETDEV_CHANGE): eth0: link becomes ready

where with .26 (with the same userland) had

eth0: RTL8169sc/8110sc at 0xf87fc000, 00:30:18:a4:65:89, XID 18000000 IRQ 18
r8169: eth0: link up
ADDRCONF(NETDEV_CHANGE): eth0: link becomes ready

Same for .31 on another box, modulo different address there...

#16 lore raw

Re: [PATCH] r8169: fix broken register writes

Quoted 7 lines · Al Viro
Quoted 6 lines
Quoted 1 line

Thanks Fran?ois. Which hardware have you tested this on so far ?

10ec:8169 (rev 10) / RTL8169sb/8110sb / XID 10000000

Timo's is a 10ec:8167 / RTL8169sc/8110sc / XID 18000000. He only tested the MAC[04] part.

Quoted 6 lines

FWIW, XID18000000 here (J7F4) loses MAC4 on shutdown; hadn't tested the patch yet. 2.6.26 (on that box) and 2.6.31 (on identical mb) work, 2.6.33 doesn't. I suspect that bisect would lead to commit cc098dc70 (i.e. the place where we started to set address on shutdown). One more data point: ifconfig hw ether done under 2.6.26 did restore the address. And that's the same function, isn't it?

As the matter of fact, ifconfig eth0 hw ether .... ends up zeroing upper 32 bits on old kernels once in a while.

What orders accesses as seen by PCI bus in

        RTL_W8(Cfg9346, Cfg9346_Unlock);
        RTL_W32(MAC0, low);
        RTL_W32(MAC4, high);
        RTL_W8(Cfg9346, Cfg9346_Lock);

anyway, and don't we need mmiowb() or two in there?

#17 lore raw

Re: [PATCH] r8169: fix broken register writes

Quoted 16 lines · Al Viro
Quoted 7 lines · Al Viro
Quoted 6 lines
Quoted 1 line

Thanks Fran?ois. Which hardware have you tested this on so far ?

10ec:8169 (rev 10) / RTL8169sb/8110sb / XID 10000000

Timo's is a 10ec:8167 / RTL8169sc/8110sc / XID 18000000. He only tested the MAC[04] part.

Quoted 6 lines

FWIW, XID18000000 here (J7F4) loses MAC4 on shutdown; hadn't tested the patch yet. 2.6.26 (on that box) and 2.6.31 (on identical mb) work, 2.6.33 doesn't. I suspect that bisect would lead to commit cc098dc70 (i.e. the place where we started to set address on shutdown). One more data point: ifconfig hw ether done under 2.6.26 did restore the address. And that's the same function, isn't it?

Quoted 2 lines

As the matter of fact, ifconfig eth0 hw ether .... ends up zeroing upper 32 bits on old kernels once in a while.

BTW, patch from upthread doesn't help on that box, and neither does simple reordering of MAC0 and MAC4 writes. Adding reads of MAC0 and MAC4 after corresponding writes seems to work.

#19 lore raw

Re: [PATCH] r8169: fix broken register writes

In reply to Al Viro

Al Viro <[email protected]> :
[...]

Quoted 6 lines

FWIW, XID18000000 here (J7F4) loses MAC4 on shutdown; hadn't tested the patch yet. 2.6.26 (on that box) and 2.6.31 (on identical mb) work, 2.6.33 doesn't. I suspect that bisect would lead to commit cc098dc70 (i.e. the place where we started to set address on shutdown). One more data point: ifconfig hw ether done under 2.6.26 did restore the address. And that's the same function, isn't it?

You are right.

Quoted 7 lines

Another interesting bit: unlike the older kernel, grep for eth0 in .33 dmesg

eth0: RTL8169sc/8110sc at 0xf87fc000, 00:30:18:a4:65:89, XID 18000000 IRQ 18
r8169: eth0: link down
ADDRCONF(NETDEV_UP): eth0: link is not ready
r8169: eth0: link up
ADDRCONF(NETDEV_CHANGE): eth0: link becomes ready

Remove rtl8169scd_hw_phy_config ?

[...]

Quoted 1 line

Same for .31 on another box, modulo different address there...

No, keep it.

At first sight it looks like rtl8169_open::rtl8169_check_link_status and a LinkChg interrupt (order eventually reversed) while 2.6.26 did not notice the interrupt.

Signature · 1 line
Ueimor
#18 lore raw

Re: [PATCH] r8169: fix broken register writes

In reply to Al Viro

Al Viro <[email protected]> :
[...]

Quoted 3 lines

BTW, patch from upthread doesn't help on that box, and neither does simple reordering of MAC0 and MAC4 writes. Adding reads of MAC0 and MAC4 after corresponding writes seems to work.

Does something like the patch below work too ?

I'd like to factor out the posted PCI write commits.

drivers/net/r8169.c +10 -0
index 9674005..8d1ab0f 100644
@@ -542,6 +542,11 @@ static int rtl8169_poll(struct napi_struct *napi, int budget);
 static const unsigned int rtl8169_rx_config =
 	(RX_FIFO_THRESH << RxCfgFIFOShift) | (RX_DMA_BURST << RxCfgDMAShift);
 
+static void r816x_pci_write_commit(void __iomem *ioaddr)
+{
+	RTL_R8(ChipCmd);
+}
+
 static void mdio_write(void __iomem *ioaddr, int reg_addr, int value)
 {
 	int i;
@@ -2825,8 +2830,13 @@ static void rtl_rar_set(struct rtl8169_private *tp, u8 *addr)
 	spin_lock_irq(&tp->lock);
 
 	RTL_W8(Cfg9346, Cfg9346_Unlock);
+
 	RTL_W32(MAC4, high);
+	r816x_pci_write_commit(ioaddr);
+
 	RTL_W32(MAC0, low);
+	r816x_pci_write_commit(ioaddr);
+
 	RTL_W8(Cfg9346, Cfg9346_Lock);
 
 	spin_unlock_irq(&tp->lock);