> However, I've located one more problem which I don't know yet how to fix > correctly. > AFAIR, device may pass several incoming frames in one urb, and second > and later frames are 2-byte-aligned. > This may cause situations when IP layer gets IP packet not aligned at > 32-bit word boundary and occasionally crash because of unligned access > (hardware and/or codebase I'm working with really dislikes unaligned > accesses from kernel). > > Looks the only way to fix that is to detect such cases, and copy data? > But this will hurt performance on systems that can handle unaligned > accesses ...
Attached is a patch that handles this, based on additional Kconfig key. I've tested this on hardware and kernel I'm working with, and then forward-ported to 2.6.19-pre6 Signed-off-by: Nikita Youshchenko <[EMAIL PROTECTED]> Nikita
diff -ur net.orig/asix.c net/asix.c --- net.orig/asix.c 2006-10-15 16:20:26.000000000 +0400 +++ net/asix.c 2006-11-24 07:53:03.277679810 +0300 @@ -697,6 +697,7 @@ char *packet; struct sk_buff *ax_skb; u16 size; + int offset; head = (u8 *) skb->data; memcpy(&header, head, sizeof(header)); @@ -713,8 +714,20 @@ /* get the packet length */ size = (u16) (header & 0x0000ffff); - if ((skb->len) - ((size + 1) & 0xfffe) == 0) + if ((skb->len) - ((size + 1) & 0xfffe) == 0) { +#ifdef CONFIG_USB_NET_AX8817X_ALIGN + offset = ((unsigned long)packet + 2) & 3; +#else + offset = 0; +#endif + if (offset) { + skb->data -= offset; + skb->tail -= offset; + memmove(packet - offset, packet, size); + } + return 2; + } if (size > ETH_FRAME_LEN) { devdbg(dev,"invalid rx length %d", size); return 0; @@ -722,8 +735,17 @@ ax_skb = skb_clone(skb, GFP_ATOMIC); if (ax_skb) { ax_skb->len = size; - ax_skb->data = packet; - ax_skb->tail = packet + size; + +#ifdef CONFIG_USB_NET_AX8817X_ALIGN + offset = ((unsigned long)packet + 2) & 3; +#else + offset = 0; +#endif + ax_skb->data = packet - offset; + ax_skb->tail = packet - offset + size; + if (offset) + memmove(packet - offset, packet, size); + usbnet_skb_return(dev, ax_skb); } else { return 0; diff -ur net.orig/Kconfig net/Kconfig --- net.orig/Kconfig 2006-10-15 16:20:26.000000000 +0400 +++ net/Kconfig 2006-11-24 07:49:16.155519445 +0300 @@ -153,6 +153,27 @@ This driver creates an interface named "ethX", where X depends on what other networking devices you have in use. +config USB_AX8817X_ALIGN + boolean "ASIX AX88xxx: align incoming frames" + depends on USB_NET_AX8817X + default y if MIPS || ARM + default n if X86 || X86_64 + help + AX88xxx chips sometimes packs several network frames into same USB + data block. This may cause payload of second and subsequent frames + not to be aligned at 32bit boundary, which in turn may cause large + performance penalties or even kernel crashes on some RISC processors. + + Answering Y here will add to driver code that detects incorrectly + aligned frames, and manually moves those to fix alignment. This + fixes the issue for processors that have it, but only causes + unneeded performance penalty on processors that have no problems + with unaligned data access (such as x86 PC processors). + + If unsure, say N. + + If you are experiencing kernel crashes when using AX88xxx-based + hardware, answer Y. config USB_NET_CDCETHER tristate "CDC Ethernet support (smart devices such as cable modems)"
pgpE31SZVOAKW.pgp
Description: PGP signature
------------------------------------------------------------------------- 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
_______________________________________________ linux-usb-devel@lists.sourceforge.net To unsubscribe, use the last form field at: https://lists.sourceforge.net/lists/listinfo/linux-usb-devel