• Al Viro's avatar
    [TG3]: Endianness bugfix. · 286e310f
    Al Viro authored
    tg3_nvram_write_block_unbuffered() is reading data from nvram into
    allocated buffer before overwriting a part of it with user-supplied
    data.  Then it feeds the entire page back to nvram.  It should be
    storing the words it had read as little-endian, not as host-endian.
    Note that tg3_set_eeprom() does exactly that for padding the same
    data to full words before it gets passed down to tg3_nvram_write_block()
    and then to tg3_nvram_write_block_unbuffered().
    
    Moreover, when we get to sending the entire thing back to nvram, we
    go through it word-by-word, doing essentially
    	writel(swab32(le32_to_cpu(word)), ...)
    so if we want them to reach the card in host-independent endianness,
    we'd better really have all that buffer filled with fixed-endian.
    For user-supplied part we obviously do have that (it's an array of
    octets memcpy'd in), ditto for padding of user-supplied part to word
    boundaries (taken care of in tg3_set_eeprom()).  The rest of the
    buffer gets filled by tg3_nvram_write_block_unbuffered() and it would
    damn better be consistent with that (and with tg3_get_eeprom(), while
    we are at it - there we also convert the words read from nvram to
    little-endian before returning the buffer to user).
    
    The bug should get triggered on big-endian boxen when set_eeprom is done
    for less than entire page.  Then the words that should've been unaffected
    at all will actually get byteswapped in place in nvram.
    Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
    Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
    286e310f
tg3.c 366 KB