• Pavel Roskin's avatar
    [PATCH] Tulip endianess fix · d86d6aaa
    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
tulip_core.c 54 KB