diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-05-21 06:04:44 +0200 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-05-21 06:04:44 +0200 |
commit | f8965467f366fd18f01feafb5db10512d7b4422c (patch) | |
tree | 3706a9cd779859271ca61b85c63a1bc3f82d626e /drivers/net/usb/asix.c | |
parent | Merge branch 'docs-next' of git://git.lwn.net/linux-2.6 (diff) | |
parent | Merge branch 'master' of /home/davem/src/GIT/linux-2.6/ (diff) | |
download | linux-f8965467f366fd18f01feafb5db10512d7b4422c.tar.xz linux-f8965467f366fd18f01feafb5db10512d7b4422c.zip |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6: (1674 commits)
qlcnic: adding co maintainer
ixgbe: add support for active DA cables
ixgbe: dcb, do not tag tc_prio_control frames
ixgbe: fix ixgbe_tx_is_paused logic
ixgbe: always enable vlan strip/insert when DCB is enabled
ixgbe: remove some redundant code in setting FCoE FIP filter
ixgbe: fix wrong offset to fc_frame_header in ixgbe_fcoe_ddp
ixgbe: fix header len when unsplit packet overflows to data buffer
ipv6: Never schedule DAD timer on dead address
ipv6: Use POSTDAD state
ipv6: Use state_lock to protect ifa state
ipv6: Replace inet6_ifaddr->dead with state
cxgb4: notify upper drivers if the device is already up when they load
cxgb4: keep interrupts available when the ports are brought down
cxgb4: fix initial addition of MAC address
cnic: Return SPQ credit to bnx2x after ring setup and shutdown.
cnic: Convert cnic_local_flags to atomic ops.
can: Fix SJA1000 command register writes on SMP systems
bridge: fix build for CONFIG_SYSFS disabled
ARCNET: Limit com20020 PCI ID matches for SOHARD cards
...
Fix up various conflicts with pcmcia tree drivers/net/
{pcmcia/3c589_cs.c, wireless/orinoco/orinoco_cs.c and
wireless/orinoco/spectrum_cs.c} and feature removal
(Documentation/feature-removal-schedule.txt).
Also fix a non-content conflict due to pm_qos_requirement getting
renamed in the PM tree (now pm_qos_request) in net/mac80211/scan.c
Diffstat (limited to 'drivers/net/usb/asix.c')
-rw-r--r-- | drivers/net/usb/asix.c | 53 |
1 files changed, 40 insertions, 13 deletions
diff --git a/drivers/net/usb/asix.c b/drivers/net/usb/asix.c index 35f56fc82803..31b73310ec77 100644 --- a/drivers/net/usb/asix.c +++ b/drivers/net/usb/asix.c @@ -224,10 +224,9 @@ static int asix_write_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index, cmd, value, index, size); if (data) { - buf = kmalloc(size, GFP_KERNEL); + buf = kmemdup(data, size, GFP_KERNEL); if (!buf) goto out; - memcpy(buf, data, size); } err = usb_control_msg( @@ -322,8 +321,29 @@ static int asix_rx_fixup(struct usbnet *dev, struct sk_buff *skb) /* get the packet length */ size = (u16) (header & 0x0000ffff); - if ((skb->len) - ((size + 1) & 0xfffe) == 0) + if ((skb->len) - ((size + 1) & 0xfffe) == 0) { + u8 alignment = (u32)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; + } + if (size > ETH_FRAME_LEN) { netdev_err(dev->net, "asix_rx_fixup() Bad RX Length %d\n", size); @@ -331,7 +351,18 @@ static int asix_rx_fixup(struct usbnet *dev, struct sk_buff *skb) } ax_skb = skb_clone(skb, GFP_ATOMIC); if (ax_skb) { + u8 alignment = (u32)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); @@ -558,16 +589,14 @@ static void asix_set_multicast(struct net_device *net) * for our 8 byte filter buffer * to avoid allocating memory that * is tricky to free later */ - struct dev_mc_list *mc_list; + struct netdev_hw_addr *ha; u32 crc_bits; memset(data->multi_filter, 0, AX_MCAST_FILTER_SIZE); /* Build the multicast hash filter. */ - netdev_for_each_mc_addr(mc_list, net) { - crc_bits = - ether_crc(ETH_ALEN, - mc_list->dmi_addr) >> 26; + netdev_for_each_mc_addr(ha, net) { + crc_bits = ether_crc(ETH_ALEN, ha->addr) >> 26; data->multi_filter[crc_bits >> 3] |= 1 << (crc_bits & 7); } @@ -794,16 +823,14 @@ static void ax88172_set_multicast(struct net_device *net) * for our 8 byte filter buffer * to avoid allocating memory that * is tricky to free later */ - struct dev_mc_list *mc_list; + struct netdev_hw_addr *ha; u32 crc_bits; memset(data->multi_filter, 0, AX_MCAST_FILTER_SIZE); /* Build the multicast hash filter. */ - netdev_for_each_mc_addr(mc_list, net) { - crc_bits = - ether_crc(ETH_ALEN, - mc_list->dmi_addr) >> 26; + netdev_for_each_mc_addr(ha, net) { + crc_bits = ether_crc(ETH_ALEN, ha->addr) >> 26; data->multi_filter[crc_bits >> 3] |= 1 << (crc_bits & 7); } |