diff options
author | David S. Miller <davem@davemloft.net> | 2013-04-22 20:32:51 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-04-22 20:32:51 -0400 |
commit | 6e0895c2ea326cc4bb11e8fa2f654628d5754c31 (patch) | |
tree | 7089303ac11a12edc43a8c4fa1b23974e10937ea /drivers/net/usb | |
parent | 55fbbe46e9eb3cbe6c335503f5550855a1128dce (diff) | |
parent | 60d509fa6a9c4653a86ad830e4c4b30360b23f0e (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Conflicts:
drivers/net/ethernet/emulex/benet/be_main.c
drivers/net/ethernet/intel/igb/igb_main.c
drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
include/net/scm.h
net/batman-adv/routing.c
net/ipv4/tcp_input.c
The e{uid,gid} --> {uid,gid} credentials fix conflicted with the
cleanup in net-next to now pass cred structs around.
The be2net driver had a bug fix in 'net' that overlapped with the VLAN
interface changes by Patrick McHardy in net-next.
An IGB conflict existed because in 'net' the build_skb() support was
reverted, and in 'net-next' there was a comment style fix within that
code.
Several batman-adv conflicts were resolved by making sure that all
calls to batadv_is_my_mac() are changed to have a new bat_priv first
argument.
Eric Dumazet's TS ECR fix in TCP in 'net' conflicted with the F-RTO
rewrite in 'net-next', mostly overlapping changes.
Thanks to Stephen Rothwell and Antonio Quartulli for help with several
of these merge resolutions.
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/usb')
-rw-r--r-- | drivers/net/usb/cdc_mbim.c | 2 | ||||
-rw-r--r-- | drivers/net/usb/qmi_wwan.c | 104 |
2 files changed, 105 insertions, 1 deletions
diff --git a/drivers/net/usb/cdc_mbim.c b/drivers/net/usb/cdc_mbim.c index cc6dfe4102fd..c96454434f7b 100644 --- a/drivers/net/usb/cdc_mbim.c +++ b/drivers/net/usb/cdc_mbim.c | |||
@@ -134,7 +134,7 @@ static struct sk_buff *cdc_mbim_tx_fixup(struct usbnet *dev, struct sk_buff *skb | |||
134 | goto error; | 134 | goto error; |
135 | 135 | ||
136 | if (skb) { | 136 | if (skb) { |
137 | if (skb->len <= sizeof(ETH_HLEN)) | 137 | if (skb->len <= ETH_HLEN) |
138 | goto error; | 138 | goto error; |
139 | 139 | ||
140 | /* mapping VLANs to MBIM sessions: | 140 | /* mapping VLANs to MBIM sessions: |
diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c index 968d5d50751d..2a3579f67910 100644 --- a/drivers/net/usb/qmi_wwan.c +++ b/drivers/net/usb/qmi_wwan.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <linux/module.h> | 13 | #include <linux/module.h> |
14 | #include <linux/netdevice.h> | 14 | #include <linux/netdevice.h> |
15 | #include <linux/ethtool.h> | 15 | #include <linux/ethtool.h> |
16 | #include <linux/etherdevice.h> | ||
16 | #include <linux/mii.h> | 17 | #include <linux/mii.h> |
17 | #include <linux/usb.h> | 18 | #include <linux/usb.h> |
18 | #include <linux/usb/cdc.h> | 19 | #include <linux/usb/cdc.h> |
@@ -52,6 +53,96 @@ struct qmi_wwan_state { | |||
52 | struct usb_interface *data; | 53 | struct usb_interface *data; |
53 | }; | 54 | }; |
54 | 55 | ||
56 | /* default ethernet address used by the modem */ | ||
57 | static const u8 default_modem_addr[ETH_ALEN] = {0x02, 0x50, 0xf3}; | ||
58 | |||
59 | /* Make up an ethernet header if the packet doesn't have one. | ||
60 | * | ||
61 | * A firmware bug common among several devices cause them to send raw | ||
62 | * IP packets under some circumstances. There is no way for the | ||
63 | * driver/host to know when this will happen. And even when the bug | ||
64 | * hits, some packets will still arrive with an intact header. | ||
65 | * | ||
66 | * The supported devices are only capably of sending IPv4, IPv6 and | ||
67 | * ARP packets on a point-to-point link. Any packet with an ethernet | ||
68 | * header will have either our address or a broadcast/multicast | ||
69 | * address as destination. ARP packets will always have a header. | ||
70 | * | ||
71 | * This means that this function will reliably add the appropriate | ||
72 | * header iff necessary, provided our hardware address does not start | ||
73 | * with 4 or 6. | ||
74 | * | ||
75 | * Another common firmware bug results in all packets being addressed | ||
76 | * to 00:a0:c6:00:00:00 despite the host address being different. | ||
77 | * This function will also fixup such packets. | ||
78 | */ | ||
79 | static int qmi_wwan_rx_fixup(struct usbnet *dev, struct sk_buff *skb) | ||
80 | { | ||
81 | __be16 proto; | ||
82 | |||
83 | /* usbnet rx_complete guarantees that skb->len is at least | ||
84 | * hard_header_len, so we can inspect the dest address without | ||
85 | * checking skb->len | ||
86 | */ | ||
87 | switch (skb->data[0] & 0xf0) { | ||
88 | case 0x40: | ||
89 | proto = htons(ETH_P_IP); | ||
90 | break; | ||
91 | case 0x60: | ||
92 | proto = htons(ETH_P_IPV6); | ||
93 | break; | ||
94 | case 0x00: | ||
95 | if (is_multicast_ether_addr(skb->data)) | ||
96 | return 1; | ||
97 | /* possibly bogus destination - rewrite just in case */ | ||
98 | skb_reset_mac_header(skb); | ||
99 | goto fix_dest; | ||
100 | default: | ||
101 | /* pass along other packets without modifications */ | ||
102 | return 1; | ||
103 | } | ||
104 | if (skb_headroom(skb) < ETH_HLEN) | ||
105 | return 0; | ||
106 | skb_push(skb, ETH_HLEN); | ||
107 | skb_reset_mac_header(skb); | ||
108 | eth_hdr(skb)->h_proto = proto; | ||
109 | memset(eth_hdr(skb)->h_source, 0, ETH_ALEN); | ||
110 | fix_dest: | ||
111 | memcpy(eth_hdr(skb)->h_dest, dev->net->dev_addr, ETH_ALEN); | ||
112 | return 1; | ||
113 | } | ||
114 | |||
115 | /* very simplistic detection of IPv4 or IPv6 headers */ | ||
116 | static bool possibly_iphdr(const char *data) | ||
117 | { | ||
118 | return (data[0] & 0xd0) == 0x40; | ||
119 | } | ||
120 | |||
121 | /* disallow addresses which may be confused with IP headers */ | ||
122 | static int qmi_wwan_mac_addr(struct net_device *dev, void *p) | ||
123 | { | ||
124 | int ret; | ||
125 | struct sockaddr *addr = p; | ||
126 | |||
127 | ret = eth_prepare_mac_addr_change(dev, p); | ||
128 | if (ret < 0) | ||
129 | return ret; | ||
130 | if (possibly_iphdr(addr->sa_data)) | ||
131 | return -EADDRNOTAVAIL; | ||
132 | eth_commit_mac_addr_change(dev, p); | ||
133 | return 0; | ||
134 | } | ||
135 | |||
136 | static const struct net_device_ops qmi_wwan_netdev_ops = { | ||
137 | .ndo_open = usbnet_open, | ||
138 | .ndo_stop = usbnet_stop, | ||
139 | .ndo_start_xmit = usbnet_start_xmit, | ||
140 | .ndo_tx_timeout = usbnet_tx_timeout, | ||
141 | .ndo_change_mtu = usbnet_change_mtu, | ||
142 | .ndo_set_mac_address = qmi_wwan_mac_addr, | ||
143 | .ndo_validate_addr = eth_validate_addr, | ||
144 | }; | ||
145 | |||
55 | /* using a counter to merge subdriver requests with our own into a combined state */ | 146 | /* using a counter to merge subdriver requests with our own into a combined state */ |
56 | static int qmi_wwan_manage_power(struct usbnet *dev, int on) | 147 | static int qmi_wwan_manage_power(struct usbnet *dev, int on) |
57 | { | 148 | { |
@@ -229,6 +320,18 @@ next_desc: | |||
229 | usb_driver_release_interface(driver, info->data); | 320 | usb_driver_release_interface(driver, info->data); |
230 | } | 321 | } |
231 | 322 | ||
323 | /* Never use the same address on both ends of the link, even | ||
324 | * if the buggy firmware told us to. | ||
325 | */ | ||
326 | if (!compare_ether_addr(dev->net->dev_addr, default_modem_addr)) | ||
327 | eth_hw_addr_random(dev->net); | ||
328 | |||
329 | /* make MAC addr easily distinguishable from an IP header */ | ||
330 | if (possibly_iphdr(dev->net->dev_addr)) { | ||
331 | dev->net->dev_addr[0] |= 0x02; /* set local assignment bit */ | ||
332 | dev->net->dev_addr[0] &= 0xbf; /* clear "IP" bit */ | ||
333 | } | ||
334 | dev->net->netdev_ops = &qmi_wwan_netdev_ops; | ||
232 | err: | 335 | err: |
233 | return status; | 336 | return status; |
234 | } | 337 | } |
@@ -307,6 +410,7 @@ static const struct driver_info qmi_wwan_info = { | |||
307 | .bind = qmi_wwan_bind, | 410 | .bind = qmi_wwan_bind, |
308 | .unbind = qmi_wwan_unbind, | 411 | .unbind = qmi_wwan_unbind, |
309 | .manage_power = qmi_wwan_manage_power, | 412 | .manage_power = qmi_wwan_manage_power, |
413 | .rx_fixup = qmi_wwan_rx_fixup, | ||
310 | }; | 414 | }; |
311 | 415 | ||
312 | #define HUAWEI_VENDOR_ID 0x12D1 | 416 | #define HUAWEI_VENDOR_ID 0x12D1 |