Problem with 3Com 10/100 Ethernet card not being recognized

From ThinkWiki
Revision as of 13:36, 27 February 2006 by Wyrfel (Talk | contribs) (Using setpci)
Jump to: navigation, search

Information about the problem of non-recognized 3Com Ethernet card when using ACPI with 2.6 kernels.

Problem description

When using a 2.6 kernel with ACPI enabled, the card is not recognized properly. In fact the kernel finds the card and tries to enable it but gives an error message in dmesg output.

Affected Models

Affected Operating Systems

  • All Linux kernels prior to 2.6.14-rc1.

Status

Fixed. This was a problem with the PCI power management and resource management, which occurs when the ACPI subsystem is enabled. It is tracked in issue 158725 in RedHat's Bugzilla and issue 1188 in the kernel.org Bugzilla. The former contains kernel patches.

Solutions

This problem is fixed in mainline kernels 2.6.14-rc1 and newer.

Disabling ACPI-PCI control or ACPI

Try one of the following kernel parameters (in that order):

  • nolapic (disables support for local apic)
  • acpi=nopci (disables PCI resource control of the ACPI subsystem)
  • acpi=off (completely disables ACPI, should always work)

Using setpci

It is possible to get the ethernet controller of the 3Com combo card working with ACPI enabled by using the setpci command. Since it requires an IO port address that may change each boot, this Perl script will help to automate things. It has only been tested under the 2.6.12-rc5-mm2 and 2.6.12-rc6 kernels with the 3c59x driver compiled as a module. It may break with different versions of the lspci command (tested with 2.1.11).

#!/usr/bin/perl

use strict;

my $DRIVER = "3c59x";
my $VENDOR = "10b7";
my $DEVICE = "6056";
my $LSPCI = `lspci -vd $VENDOR:$DEVICE | grep "I/O ports"`;

print "Resetting 3Com ethernet controller... ";
if($LSPCI =~ m|I/O ports at (\d{4})|i) {
	my $io = $1;
	`rmmod $DRIVER`;
	`setpci -H1 -d $VENDOR:$DEVICE COMMAND=0x07 CACHE_LINE_SIZE=0 LATENCY_TIMER=0x40 BASE_ADDRESS_0=0x$io`;
	`modprobe $DRIVER`;
	print "done.\n";
} else {
	print "failed.\n";
}

This worked well for my X20 with an Ubuntu Breezy System (Kernel 2.6.12). Thanks for that Script.

You may use # update-rc.d -f <script_name> start 99 2 3 4 5 to have the driver loaded at every reboot.

Using pci-config

The above setpci script didn't work at boot on my X20, otherwise it works well. I tried another workaround by using pci-config. This worked nicely on Debian testing with stock kernel 2.6.12.3.

1. Install pci-config (e.g., from the net-tools package). On Debian you want to install the nictools-pci package from either testing or unstable.

2. Run # /sbin/lspci and identify the PCI device of the 3Com chip (e.g., "00:03.0").

3. Run # /usr/sbin/pci-config and identify the corresponding device# (e.g., #5).

4. Append the following to /etc/modprobe.conf using the above device#:

install 3c59x /usr/sbin/pci-config -W -#5 > /dev/null && /sbin/modprobe --ignore-install 3c59x

5. Reboot (or # rmmod 3c59x && modprobe 3c59x).

Hint:
On a Debian system you should rather add a file to /etc/modprobe.d with the contents you usually would add to /etc/modprobe.conf. I just created a file named /etc/modprobe.d/3c59x

For more information look at comment #30 in RedHat's bugzilla

Using a patch

There is a patch at http://marc.theaimsgroup.com/?l=linux-kernel&m=112247477326714&q=raw that fixed this issue on a T21 using Linux 2.6.13-rc5 - Thanks John!