summaryrefslogtreecommitdiff
path: root/drivers/net/usb/lg-vl600.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-10-25 13:25:22 +0200
committerLinus Torvalds <torvalds@linux-foundation.org>2011-10-25 13:25:22 +0200
commit8a9ea3237e7eb5c25f09e429ad242ae5a3d5ea22 (patch)
treea0a63398a9983667d52cbbbf4e2405b4f22b1d83 /drivers/net/usb/lg-vl600.c
parent1be025d3cb40cd295123af2c394f7229ef9b30ca (diff)
parent8b3408f8ee994973869d8ba32c5bf482bc4ddca4 (diff)
downloadlwn-8a9ea3237e7eb5c25f09e429ad242ae5a3d5ea22.tar.gz
lwn-8a9ea3237e7eb5c25f09e429ad242ae5a3d5ea22.zip
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next: (1745 commits) dp83640: free packet queues on remove dp83640: use proper function to free transmit time stamping packets ipv6: Do not use routes from locally generated RAs |PATCH net-next] tg3: add tx_dropped counter be2net: don't create multiple RX/TX rings in multi channel mode be2net: don't create multiple TXQs in BE2 be2net: refactor VF setup/teardown code into be_vf_setup/clear() be2net: add vlan/rx-mode/flow-control config to be_setup() net_sched: cls_flow: use skb_header_pointer() ipv4: avoid useless call of the function check_peer_pmtu TCP: remove TCP_DEBUG net: Fix driver name for mdio-gpio.c ipv4: tcp: fix TOS value in ACK messages sent from TIME_WAIT rtnetlink: Add missing manual netlink notification in dev_change_net_namespaces ipv4: fix ipsec forward performance regression jme: fix irq storm after suspend/resume route: fix ICMP redirect validation net: hold sock reference while processing tx timestamps tcp: md5: add more const attributes Add ethtool -g support to virtio_net ... Fix up conflicts in: - drivers/net/Kconfig: The split-up generated a trivial conflict with removal of a stale reference to Documentation/networking/net-modules.txt. Remove it from the new location instead. - fs/sysfs/dir.c: Fairly nasty conflicts with the sysfs rb-tree usage, conflicting with Eric Biederman's changes for tagged directories.
Diffstat (limited to 'drivers/net/usb/lg-vl600.c')
-rw-r--r--drivers/net/usb/lg-vl600.c19
1 files changed, 19 insertions, 0 deletions
diff --git a/drivers/net/usb/lg-vl600.c b/drivers/net/usb/lg-vl600.c
index 1d83ccfd7277..1e7221951056 100644
--- a/drivers/net/usb/lg-vl600.c
+++ b/drivers/net/usb/lg-vl600.c
@@ -89,6 +89,8 @@ static int vl600_bind(struct usbnet *dev, struct usb_interface *intf)
* addresses have no meaning, the destination and the source of every
* packet depend only on whether it is on the IN or OUT endpoint. */
dev->net->flags |= IFF_NOARP;
+ /* IPv6 NDP relies on multicast. Enable it by default. */
+ dev->net->flags |= IFF_MULTICAST;
return ret;
}
@@ -200,6 +202,14 @@ static int vl600_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
} else {
memset(ethhdr->h_source, 0, ETH_ALEN);
memcpy(ethhdr->h_dest, dev->net->dev_addr, ETH_ALEN);
+
+ /* Inbound IPv6 packets have an IPv4 ethertype (0x800)
+ * for some reason. Peek at the L3 header to check
+ * for IPv6 packets, and set the ethertype to IPv6
+ * (0x86dd) so Linux can understand it.
+ */
+ if ((buf->data[sizeof(*ethhdr)] & 0xf0) == 0x60)
+ ethhdr->h_proto = __constant_htons(ETH_P_IPV6);
}
if (count) {
@@ -297,6 +307,15 @@ encapsulate:
if (skb->len < full_len) /* Pad */
skb_put(skb, full_len - skb->len);
+ /* The VL600 wants IPv6 packets to have an IPv4 ethertype
+ * Check if this is an IPv6 packet, and set the ethertype
+ * to 0x800
+ */
+ if ((skb->data[sizeof(struct vl600_pkt_hdr *) + 0x22] & 0xf0) == 0x60) {
+ skb->data[sizeof(struct vl600_pkt_hdr *) + 0x20] = 0x08;
+ skb->data[sizeof(struct vl600_pkt_hdr *) + 0x21] = 0;
+ }
+
return skb;
}