-
Pavel Roskin authored
My tulip ethernet card doesn't work on Blue&White G3 PowerMac with Linux 2.6.5-rc2. The card is shown by lspci as 01:03.0 Ethernet controller: Linksys Network Everywhere Fast Ethernet 10/100 model NC100 (rev 11) The kernel detects it as "ADMtek Comet rev 17". The MAC address reported by the kernel looked obviously wrong. Also, I could only ping the system successfully if the interface was in promiscuous mode (running Ethereal). Those two symptoms indicated two different problems - one for reading the MAC address from the card on module load (tulip_init_one), and the other for writing the address to the card when the interface was brought up (tulip_up). I have fixed both, and here's the explanation: tulip_init_one: When reading the first 4 bytes of the address, inl() returns the same data to the CPU on all platforms, interpreting the data from the lowest port address as the least significant byte. In other words, I/O is little endian on all platforms; it's the memory that differs across platforms. We want to write the data to memory preserving little-endianness of the PCI bus. To force little endian write to the memory, the data should be converted to the little endian format. When reading the remaining 2 bytes, the CPU gets them in 2 least significant bytes. To write those 2 bytes to the memory in a 16-bit operation, they should be byte-swapped for the 16-bit operation. tulip_up: The first 4 bytes are processed correctly, but the code is confusing. Reading from memory needs conversion to CPU format, while writing to I/O ports doesn't. So I replaced cpu_to_le32() to le32_to_cpu(). The second 2 bytes are read in a 16-bit memory operation, so they should be passed to le16_to_cpu() rather than cpu_to_le32() to make them CPU independent and suitable for outl(). All those conversions do nothing on little-endian machines, so they should not be affected. The patch has been tested. The driver is working fine. ping is OK, ssh is OK, X11 over ssh is OK. Even netconsole is working fine.
d86d6aaa