Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 291411
b: refs/heads/master
c: a9e0aca
h: refs/heads/master
i:
  291409: 51b4aef
  291407: ae9b11f
v: v3
  • Loading branch information
Eric Dumazet authored and David S. Miller committed Mar 16, 2012
1 parent 8ebceb9 commit 626b918
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 69 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 1174764e810998e81b334b5ccdfad8a9d059c6a1
refs/heads/master: a9e0aca4b37885b5599e52211f098bd7f565e749
88 changes: 20 additions & 68 deletions trunk/drivers/net/usb/asix.c
Original file line number Diff line number Diff line change
Expand Up @@ -305,88 +305,40 @@ asix_write_cmd_async(struct usbnet *dev, u8 cmd, u16 value, u16 index,

static int asix_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
{
u8 *head;
u32 header;
char *packet;
struct sk_buff *ax_skb;
u16 size;
int offset = 0;

head = (u8 *) skb->data;
memcpy(&header, head, sizeof(header));
le32_to_cpus(&header);
packet = head + sizeof(header);
while (offset + sizeof(u32) < skb->len) {
struct sk_buff *ax_skb;
u16 size;
u32 header = get_unaligned_le32(skb->data + offset);

skb_pull(skb, 4);

while (skb->len > 0) {
if ((header & 0x07ff) != ((~header >> 16) & 0x07ff))
netdev_err(dev->net, "asix_rx_fixup() Bad Header Length\n");
offset += sizeof(u32);

/* get the packet length */
size = (u16) (header & 0x000007ff);

if ((skb->len) - ((size + 1) & 0xfffe) == 0) {
u8 alignment = (unsigned long)skb->data & 0x3;
if (alignment != 0x2) {
/*
* not 16bit aligned so use the room provided by
* the 32 bit header to align the data
*
* note we want 16bit alignment as MAC header is
* 14bytes thus ip header will be aligned on
* 32bit boundary so accessing ipheader elements
* using a cast to struct ip header wont cause
* an unaligned accesses.
*/
u8 realignment = (alignment + 2) & 0x3;
memmove(skb->data - realignment,
skb->data,
size);
skb->data -= realignment;
skb_set_tail_pointer(skb, size);
}
return 2;
size = (u16) (header & 0x7ff);
if (size != ((~header >> 16) & 0x07ff)) {
netdev_err(dev->net, "asix_rx_fixup() Bad Header Length\n");
return 0;
}

if (size > dev->net->mtu + ETH_HLEN) {
if ((size > dev->net->mtu + ETH_HLEN) ||
(size + offset > skb->len)) {
netdev_err(dev->net, "asix_rx_fixup() Bad RX Length %d\n",
size);
return 0;
}
ax_skb = skb_clone(skb, GFP_ATOMIC);
if (ax_skb) {
u8 alignment = (unsigned long)packet & 0x3;
ax_skb->len = size;

if (alignment != 0x2) {
/*
* not 16bit aligned use the room provided by
* the 32 bit header to align the data
*/
u8 realignment = (alignment + 2) & 0x3;
memmove(packet - realignment, packet, size);
packet -= realignment;
}
ax_skb->data = packet;
skb_set_tail_pointer(ax_skb, size);
usbnet_skb_return(dev, ax_skb);
} else {
ax_skb = netdev_alloc_skb_ip_align(dev->net, size);
if (!ax_skb)
return 0;
}

skb_pull(skb, (size + 1) & 0xfffe);

if (skb->len < sizeof(header))
break;
skb_put(ax_skb, size);
memcpy(ax_skb->data, skb->data + offset, size);
usbnet_skb_return(dev, ax_skb);

head = (u8 *) skb->data;
memcpy(&header, head, sizeof(header));
le32_to_cpus(&header);
packet = head + sizeof(header);
skb_pull(skb, 4);
offset += (size + 1) & 0xfffe;
}

if (skb->len < 0) {
if (skb->len != offset) {
netdev_err(dev->net, "asix_rx_fixup() Bad SKB Length %d\n",
skb->len);
return 0;
Expand Down Expand Up @@ -1541,7 +1493,7 @@ static const struct driver_info ax88772_info = {
.status = asix_status,
.link_reset = ax88772_link_reset,
.reset = ax88772_reset,
.flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_LINK_INTR,
.flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_LINK_INTR | FLAG_MULTI_PACKET,
.rx_fixup = asix_rx_fixup,
.tx_fixup = asix_tx_fixup,
};
Expand Down

0 comments on commit 626b918

Please sign in to comment.