Assistance with endian-ness
David Hollis <[email protected]>
| Newsgroups | gmane.linux.usb.devel |
|---|---|
| Message-ID | <[email protected]> |
All,
I'm trying to get any/all endian issues worked out of the asix driver so
I can be certain that it works on any platform but due to lack of access
to any big-endian hardware and lack of expertise with endian-issues, I
need some help.
Based on reports, AX88172 (older USB 2.0 Ethernet chip) devices work on
big-endian. I can personally verify that it works fine on
little-endian. This is a helpful data-point since a large majority of
the code in asix.c is shared between three different, but similar chips.
I have never received any reports that AX88772 devices (newer USB 2.0
10/100 chip) work on big-endian. I've received plenty of reports that
it doesn't.
The AX88178 chip (1GB USB 2.0) hasn't had any reports good or bad on
big-endian so I have no idea what it's status is. It would be great to
know one way or the other since it shares even more code with AX88772.
Only the respective bind() calls differ.
So to the point. I've been scouring the code a bit today and have found
these potential endian-troublespots and would like some additional eyes
to tell me if is an issue, could be an issue, or isn't relevant.
On with the show:
In asix.c, there are three register read/write functions: asix_read_cmd,
asix_write_cmd, and asix_write_cmd_async. With a recent patch,
asix_write_cmd_async() was tweaked to wrap the params to the wValue,
wIndex and wLength for the URB in cpu_to_le16(). asix_read/write_cmd()
were not modified in this way. That seems to me to be an inconsistency
that could be contributing to our issues.
asix_set_multicast() - which is used by AX88772 and AX88178, but NOT
AX88172 has this bit:
for (i = 0; i < net->mc_count; i++) {
crc_bits =
ether_crc(ETH_ALEN,
mc_list->dmi_addr) >> 26;
data->multi_filter[crc_bits >> 3] |=
1 << (crc_bits & 7);
mc_list = mc_list->next;
}
asix_write_cmd_async(dev, AX_CMD_WRITE_MULTI_FILTER, 0, 0,
AX_MCAST_FILTER_SIZE, data->multi_filter);
The multicast filter hash is created and then dumped as an 8 byte value
to the device. The ASIX chips seem to be little-endian, so do the bit
manipulations and such get hosed up on a big-endian platform or is this
legit in this case? The rx_ctl stuff here should be fine since the call
to asix_write_cmd_async() will wrap the value in cpu_to_le16().
In asix_tx_fixup(), we have two u32 values that get added to the skb
(prepended to the ethernet frame). The suspect code to me is here:
packet_len = (((skb->len - 4) ^ 0x0000ffff) << 16) + (skb->len - 4);
memcpy(skb->data, &packet_len, sizeof(packet_len));
if ((skb->len % 512) == 0) {
memcpy( skb->tail, &padbytes, sizeof(padbytes));
skb_put(skb, sizeof(padbytes));
}
Should packet_len and padbytes be run through cpu_to_le32()?
That's about all that I can see that would be causing these issues. All
of the other support functions are shared with AX88172, which reportedly
works fine.
--
David Hollis <[email protected]>
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
[email protected]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel