Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

This is a driver issue on a vintage machine (AMD K8, Nvidia chipset) running Linux 3.11 (Mint distro, but I don't think it matters).

claudius ~ # uname -a
Linux claudius 3.11.0-12-generic #19-Ubuntu SMP Wed Oct 9 16:20:46 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux
claudius ~ # lspci
00:00.0 Host bridge: NVIDIA Corporation nForce3 250Gb Host Bridge (rev a1)
00:01.0 ISA bridge: NVIDIA Corporation nForce3 250Gb LPC Bridge (rev a2)
00:01.1 SMBus: NVIDIA Corporation nForce 250Gb PCI System Management (rev a1)
00:02.0 USB controller: NVIDIA Corporation CK8S USB Controller (rev a1)
00:02.1 USB controller: NVIDIA Corporation CK8S USB Controller (rev a1)
00:02.2 USB controller: NVIDIA Corporation nForce3 EHCI USB 2.0 Controller (rev a2)
00:05.0 Bridge: NVIDIA Corporation CK8S Ethernet Controller (rev a2)
00:08.0 IDE interface: NVIDIA Corporation CK8S Parallel ATA Controller (v2.5) (rev a2)
00:0a.0 IDE interface: NVIDIA Corporation nForce3 Serial ATA Controller (rev a2)
00:0b.0 PCI bridge: NVIDIA Corporation nForce3 250Gb AGP Host to PCI Bridge (rev a2)
00:0e.0 PCI bridge: NVIDIA Corporation nForce3 250Gb PCI-to-PCI Bridge (rev a2)
00:18.0 Host bridge: Advanced Micro Devices, Inc. [AMD] K8 [Athlon64/Opteron] HyperTransport Technology Configuration
00:18.1 Host bridge: Advanced Micro Devices, Inc. [AMD] K8 [Athlon64/Opteron] Address Map
00:18.2 Host bridge: Advanced Micro Devices, Inc. [AMD] K8 [Athlon64/Opteron] DRAM Controller
00:18.3 Host bridge: Advanced Micro Devices, Inc. [AMD] K8 [Athlon64/Opteron] Miscellaneous Control
01:00.0 VGA compatible controller: NVIDIA Corporation NV34 [GeForce FX 5200] (rev a1)
02:05.0 Ethernet controller: Realtek Semiconductor Co., Ltd. RTL8169 PCI Gigabit Ethernet Controller (rev 10)

I want the kernel to load an alternative driver for my Realtek 8169 PCI ethernet card, which you can see it at the end of the list as 02:05.0. Here's the detail:

claudius ~ # lspci -s 02:05.0 -vv -nn
02:05.0 Ethernet controller [0200]: Realtek Semiconductor Co., Ltd. RTL8169 PCI Gigabit Ethernet Controller [10ec:8169] (rev 10)
    Subsystem: Realtek Semiconductor Co., Ltd. RTL8169/8110 Family PCI Gigabit Ethernet NIC [10ec:8169]
    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 A routed to IRQ 19
    Region 0: I/O ports at e800 [size=256]
    Region 1: Memory at febffc00 (32-bit, non-prefetchable) [size=256]
    Expansion ROM at febc0000 [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-

The issue is that the r8169 simply doesn't work. It may even make Linux crash. I blacklisted it in /etc/modprobe.d/.

The solution seems to be using the r8168 driver instead. (There's also a related question on this site.) You can download the source from Realtek, compile and install it, which I did. If you modprobe r8168, it loads fine but doesn't associate with the hardware, so the card doesn't show up in ifconfig.

I think this has to do with the modalias (encodes the hardware info) and the device/driver mapping in /lib/modules/*/modules.alias.

claudius ~ # cat /sys/devices/pci0000\:00/0000\:00\:0e.0/0000\:02\:05.0/modalias 
pci:v000010ECd00008169sv000010ECsd00008169bc02sc00i00

This is my card. Here's the Realtek driver mappings in the system:

claudius ~ # grep r816 /lib/modules/3.11.0-12-generic/modules.alias
alias pci:v00001186d00004300sv00001186sd00004C00bc*sc*i* r8169
alias pci:v000010ECd00008169sv*sd*bc*sc*i* r8169
alias pci:v000010ECd00008167sv*sd*bc*sc*i* r8169
alias pci:v00001186d00004300sv00001186sd00004B10bc*sc*i* r8168
alias pci:v000010ECd00008168sv*sd*bc*sc*i* r8168

I tried adding this line to the end of the file (knowing that you're not supposed to make manual edits):

alias pci:v000010ECd00008169sv000010ECsd00008169bc02sc00i00 r8168

Then unloaded and reloaded r8168 but that doesn't configure the card and there's nothing in dmesg.

What's the proper way to map my NIC to the r8168 driver? Do I have to rebuild the driver so it claims it can handle my card? Or is there some config data I have to add in the proper place?

share|improve this question

2 Answers 2

up vote 1 down vote accepted

You can force a device to use a certain device using bind. If the device is already owned by a different driver, you first have to unbind it.

If a PCI vendor ID (10ec for Realtek) and device ID combination is not recognized, you can make it get recognized at runtime with:

# echo 10ec 8169 > /sys/bus/pci/drivers/r8169/new_id

Example:

# lspci -s 04: -nnvvv
04:00.0 Ethernet controller [0200]: Realtek Semiconductor Co., Ltd. RTL-8129 [10ec:8129] (rev 10)
        Subsystem: Coreco Inc RTL8111/8168 PCIe Gigabit Ethernet (misconfigured) [11ec:8129]
        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 A routed to IRQ 3
        Region 0: I/O ports at c000 [size=256]
        Region 1: Memory at f7b40000 (32-bit, non-prefetchable) [size=256]
        [virtual] Expansion ROM at f7b00000 [disabled] [size=256K]
        Capabilities: [dc] Power Management version 1
                Flags: PMEClk- DSI- D1- D2- AuxCurrent=55mA PME(D0-,D1-,D2-,D3hot-,D3cold+)
                Status: D0 NoSoftRst- PME-Enable- DSel=0 DScale=0 PME-
        Kernel driver in use: pci-stub

# echo 0000:04:00.0 > /sys/bus/pci/drivers/pci-stub/unbind
# echo 0000:04:00.0 > /sys/bus/pci/drivers/r8169/bind
# lspci -s 04: -nnvvv
04:00.0 Ethernet controller [0200]: Realtek Semiconductor Co., Ltd. RTL-8129 [10ec:8129] (rev 10)
        Subsystem: Coreco Inc RTL8111/8168 PCIe Gigabit Ethernet (misconfigured) [11ec:8129]
        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 min, 8000ns max), Cache Line Size: 64 bytes
        Interrupt: pin A routed to IRQ 19
        Region 0: I/O ports at c000 [size=256]
        Region 1: Memory at f7b40000 (32-bit, non-prefetchable) [size=256]
        [virtual] Expansion ROM at f7b00000 [disabled] [size=256K]
        Capabilities: [dc] Power Management version 1
                Flags: PMEClk- DSI- D1- D2- AuxCurrent=55mA PME(D0-,D1-,D2-,D3hot-,D3cold+)
                Status: D0 NoSoftRst- PME-Enable- DSel=0 DScale=0 PME-
        Kernel driver in use: r8169
share|improve this answer

I got it working. (See below.)

I wouldn't have lost so much time had I not jumped to conclusions. I had a RTL8169 PCI network card to which Linux assigned the kernel tree r8169 driver. This driver is dysfunctional for my PCI RTL8169 and may even crash the system. I then found the Hetzner page (see link in question) and assumed the advice to use the Realtek r8168 applied to my situation. (It did not.) When the driver wouldn't associate with my card I stubbornly thought there should be a way to make it do so in order to get the card working. That was a dead-end street.

The solution is to browse the Realtek site itself again. They also have a driver called r8169, just like the dysfunctional driver from the Linux kernel. I tried that half a year ago. Apparently, it didn't succeed (don't remember exactly); probably due to my ineptitude. Anyway, Realtek released an updated driver in March 2014, and this driver does work! Thank you Realtek!

The happy outcome is the following (using smbclient):

smb: \> get "Zwölf Uhr mittags.ts"
getting file \Zwölf Uhr mittags.ts of size 4703186788 as Zwölf Uhr mittags.ts
(47839,3 KiloBytes/sec) (average 47839,3 KiloBytes/sec)

smb: \> get "Die heiße Spur.ts"
getting file \Die heiße Spur.ts of size 6841251568 as Die heiße Spur.ts
(48516,1 KiloBytes/sec) (average 48516,1 KiloBytes/sec)

I wasn't hoping to get 100 MB/s throughput. The WDC WD800AAJS-00B4A0 harddisk does around 95 MB/s (dd if=/dev/zero of=test.out bs=8k count=200k), but first there is a PCI bus (not PCIe!) shared bandwidth of 133 MB/s that might affect my setup (see Gigabit Ethernet: Dude, Where's My Bandwidth?), and second, well, the CPU is a trusty old AMD Athlon 64 3200+ single-core from 2003 topping out at 2200 MHz, and it's common in my experience to see Gigabit Ethernet transfer rate significantly reduced by relatively modest CPUs, be it x86/64 or ARM. So 50 MB/s is good enough.

share|improve this answer
    
Hey, I see you have rev10 of the 8169 device. Could you do me a favor and send me a dump of your EEPROM? You need this patch: git.lekensteyn.nl/peter/linux/commit/…. I want to compare it against an older EEPROM dump I have, my card suffers from amnesia which leads to a broken device (advertised as 8129). Please contact me at peter@lekensteyn.nl for more information, I can also provide a datasheet if wanted. –  Lekensteyn Jul 8 at 20:57
1  
By the way, for testing network throughput you should use iperf. On one side of the link, run iperf -s, on the other one iperf -c 10.1.2.3 (where 10.1.2.3 the IP address of the server side). –  Lekensteyn Jul 8 at 21:09

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.