aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/usb/asix.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/usb/asix.c')
-rw-r--r--drivers/net/usb/asix.c34
1 files changed, 33 insertions, 1 deletions
diff --git a/drivers/net/usb/asix.c b/drivers/net/usb/asix.c
index 8e7d2374558b..66c5e89326c1 100644
--- a/drivers/net/usb/asix.c
+++ b/drivers/net/usb/asix.c
@@ -322,8 +322,29 @@ static int asix_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
322 /* get the packet length */ 322 /* get the packet length */
323 size = (u16) (header & 0x0000ffff); 323 size = (u16) (header & 0x0000ffff);
324 324
325 if ((skb->len) - ((size + 1) & 0xfffe) == 0) 325 if ((skb->len) - ((size + 1) & 0xfffe) == 0) {
326 u8 alignment = (u32)skb->data & 0x3;
327 if (alignment != 0x2) {
328 /*
329 * not 16bit aligned so use the room provided by
330 * the 32 bit header to align the data
331 *
332 * note we want 16bit alignment as MAC header is
333 * 14bytes thus ip header will be aligned on
334 * 32bit boundary so accessing ipheader elements
335 * using a cast to struct ip header wont cause
336 * an unaligned accesses.
337 */
338 u8 realignment = (alignment + 2) & 0x3;
339 memmove(skb->data - realignment,
340 skb->data,
341 size);
342 skb->data -= realignment;
343 skb_set_tail_pointer(skb, size);
344 }
326 return 2; 345 return 2;
346 }
347
327 if (size > ETH_FRAME_LEN) { 348 if (size > ETH_FRAME_LEN) {
328 netdev_err(dev->net, "asix_rx_fixup() Bad RX Length %d\n", 349 netdev_err(dev->net, "asix_rx_fixup() Bad RX Length %d\n",
329 size); 350 size);
@@ -331,7 +352,18 @@ static int asix_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
331 } 352 }
332 ax_skb = skb_clone(skb, GFP_ATOMIC); 353 ax_skb = skb_clone(skb, GFP_ATOMIC);
333 if (ax_skb) { 354 if (ax_skb) {
355 u8 alignment = (u32)packet & 0x3;
334 ax_skb->len = size; 356 ax_skb->len = size;
357
358 if (alignment != 0x2) {
359 /*
360 * not 16bit aligned use the room provided by
361 * the 32 bit header to align the data
362 */
363 u8 realignment = (alignment + 2) & 0x3;
364 memmove(packet - realignment, packet, size);
365 packet -= realignment;
366 }
335 ax_skb->data = packet; 367 ax_skb->data = packet;
336 skb_set_tail_pointer(ax_skb, size); 368 skb_set_tail_pointer(ax_skb, size);
337 usbnet_skb_return(dev, ax_skb); 369 usbnet_skb_return(dev, ax_skb);