aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/usb
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/usb')
-rw-r--r--drivers/net/usb/Kconfig15
-rw-r--r--drivers/net/usb/Makefile1
-rw-r--r--drivers/net/usb/cdc_eem.c4
-rw-r--r--drivers/net/usb/cdc_ether.c37
-rw-r--r--drivers/net/usb/cdc_ncm.c6
-rw-r--r--drivers/net/usb/cdc_subset.c8
-rw-r--r--drivers/net/usb/gl620a.c2
-rw-r--r--drivers/net/usb/ipheth.c14
-rw-r--r--drivers/net/usb/kaweth.c2
-rw-r--r--drivers/net/usb/lg-vl600.c346
-rw-r--r--drivers/net/usb/net1080.c2
-rw-r--r--drivers/net/usb/plusb.c2
-rw-r--r--drivers/net/usb/rndis_host.c2
-rw-r--r--drivers/net/usb/smsc95xx.c34
-rw-r--r--drivers/net/usb/usbnet.c31
-rw-r--r--drivers/net/usb/zaurus.c8
16 files changed, 471 insertions, 43 deletions
diff --git a/drivers/net/usb/Kconfig b/drivers/net/usb/Kconfig
index 6f600cced6e1..3ec22c307797 100644
--- a/drivers/net/usb/Kconfig
+++ b/drivers/net/usb/Kconfig
@@ -433,4 +433,19 @@ config USB_SIERRA_NET
433 To compile this driver as a module, choose M here: the 433 To compile this driver as a module, choose M here: the
434 module will be called sierra_net. 434 module will be called sierra_net.
435 435
436config USB_VL600
437 tristate "LG VL600 modem dongle"
438 depends on USB_NET_CDCETHER
439 select USB_ACM
440 help
441 Select this if you want to use an LG Electronics 4G/LTE usb modem
442 called VL600. This driver only handles the ethernet
443 interface exposed by the modem firmware. To establish a connection
444 you will first need a userspace program that sends the right
445 command to the modem through its CDC ACM port, and most
446 likely also a DHCP client. See this thread about using the
447 4G modem from Verizon:
448
449 http://ubuntuforums.org/showpost.php?p=10589647&postcount=17
450
436endmenu 451endmenu
diff --git a/drivers/net/usb/Makefile b/drivers/net/usb/Makefile
index cac170301187..c7ec8a5f0a90 100644
--- a/drivers/net/usb/Makefile
+++ b/drivers/net/usb/Makefile
@@ -27,4 +27,5 @@ obj-$(CONFIG_USB_IPHETH) += ipheth.o
27obj-$(CONFIG_USB_SIERRA_NET) += sierra_net.o 27obj-$(CONFIG_USB_SIERRA_NET) += sierra_net.o
28obj-$(CONFIG_USB_NET_CX82310_ETH) += cx82310_eth.o 28obj-$(CONFIG_USB_NET_CX82310_ETH) += cx82310_eth.o
29obj-$(CONFIG_USB_NET_CDC_NCM) += cdc_ncm.o 29obj-$(CONFIG_USB_NET_CDC_NCM) += cdc_ncm.o
30obj-$(CONFIG_USB_VL600) += lg-vl600.o
30 31
diff --git a/drivers/net/usb/cdc_eem.c b/drivers/net/usb/cdc_eem.c
index 5f3b97668e63..882f53f708df 100644
--- a/drivers/net/usb/cdc_eem.c
+++ b/drivers/net/usb/cdc_eem.c
@@ -190,7 +190,7 @@ static int eem_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
190 190
191 /* 191 /*
192 * EEM packet header format: 192 * EEM packet header format:
193 * b0..14: EEM type dependant (Data or Command) 193 * b0..14: EEM type dependent (Data or Command)
194 * b15: bmType 194 * b15: bmType
195 */ 195 */
196 header = get_unaligned_le16(skb->data); 196 header = get_unaligned_le16(skb->data);
@@ -340,7 +340,7 @@ next:
340 340
341static const struct driver_info eem_info = { 341static const struct driver_info eem_info = {
342 .description = "CDC EEM Device", 342 .description = "CDC EEM Device",
343 .flags = FLAG_ETHER, 343 .flags = FLAG_ETHER | FLAG_POINTTOPOINT,
344 .bind = eem_bind, 344 .bind = eem_bind,
345 .rx_fixup = eem_rx_fixup, 345 .rx_fixup = eem_rx_fixup,
346 .tx_fixup = eem_tx_fixup, 346 .tx_fixup = eem_tx_fixup,
diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c
index 9a60e415d76b..c924ea2bce07 100644
--- a/drivers/net/usb/cdc_ether.c
+++ b/drivers/net/usb/cdc_ether.c
@@ -378,7 +378,7 @@ static void dumpspeed(struct usbnet *dev, __le32 *speeds)
378 __le32_to_cpu(speeds[1]) / 1000); 378 __le32_to_cpu(speeds[1]) / 1000);
379} 379}
380 380
381static void cdc_status(struct usbnet *dev, struct urb *urb) 381void usbnet_cdc_status(struct usbnet *dev, struct urb *urb)
382{ 382{
383 struct usb_cdc_notification *event; 383 struct usb_cdc_notification *event;
384 384
@@ -418,8 +418,9 @@ static void cdc_status(struct usbnet *dev, struct urb *urb)
418 break; 418 break;
419 } 419 }
420} 420}
421EXPORT_SYMBOL_GPL(usbnet_cdc_status);
421 422
422static int cdc_bind(struct usbnet *dev, struct usb_interface *intf) 423int usbnet_cdc_bind(struct usbnet *dev, struct usb_interface *intf)
423{ 424{
424 int status; 425 int status;
425 struct cdc_state *info = (void *) &dev->data; 426 struct cdc_state *info = (void *) &dev->data;
@@ -441,6 +442,7 @@ static int cdc_bind(struct usbnet *dev, struct usb_interface *intf)
441 */ 442 */
442 return 0; 443 return 0;
443} 444}
445EXPORT_SYMBOL_GPL(usbnet_cdc_bind);
444 446
445static int cdc_manage_power(struct usbnet *dev, int on) 447static int cdc_manage_power(struct usbnet *dev, int on)
446{ 448{
@@ -450,25 +452,26 @@ static int cdc_manage_power(struct usbnet *dev, int on)
450 452
451static const struct driver_info cdc_info = { 453static const struct driver_info cdc_info = {
452 .description = "CDC Ethernet Device", 454 .description = "CDC Ethernet Device",
453 .flags = FLAG_ETHER, 455 .flags = FLAG_ETHER | FLAG_POINTTOPOINT,
454 // .check_connect = cdc_check_connect, 456 // .check_connect = cdc_check_connect,
455 .bind = cdc_bind, 457 .bind = usbnet_cdc_bind,
456 .unbind = usbnet_cdc_unbind, 458 .unbind = usbnet_cdc_unbind,
457 .status = cdc_status, 459 .status = usbnet_cdc_status,
458 .manage_power = cdc_manage_power, 460 .manage_power = cdc_manage_power,
459}; 461};
460 462
461static const struct driver_info mbm_info = { 463static const struct driver_info wwan_info = {
462 .description = "Mobile Broadband Network Device", 464 .description = "Mobile Broadband Network Device",
463 .flags = FLAG_WWAN, 465 .flags = FLAG_WWAN,
464 .bind = cdc_bind, 466 .bind = usbnet_cdc_bind,
465 .unbind = usbnet_cdc_unbind, 467 .unbind = usbnet_cdc_unbind,
466 .status = cdc_status, 468 .status = usbnet_cdc_status,
467 .manage_power = cdc_manage_power, 469 .manage_power = cdc_manage_power,
468}; 470};
469 471
470/*-------------------------------------------------------------------------*/ 472/*-------------------------------------------------------------------------*/
471 473
474#define HUAWEI_VENDOR_ID 0x12D1
472 475
473static const struct usb_device_id products [] = { 476static const struct usb_device_id products [] = {
474/* 477/*
@@ -560,6 +563,13 @@ static const struct usb_device_id products [] = {
560 .driver_info = 0, 563 .driver_info = 0,
561}, 564},
562 565
566/* LG Electronics VL600 wants additional headers on every frame */
567{
568 USB_DEVICE_AND_INTERFACE_INFO(0x1004, 0x61aa, USB_CLASS_COMM,
569 USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE),
570 .driver_info = (unsigned long)&wwan_info,
571},
572
563/* 573/*
564 * WHITELIST!!! 574 * WHITELIST!!!
565 * 575 *
@@ -578,8 +588,17 @@ static const struct usb_device_id products [] = {
578}, { 588}, {
579 USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_MDLM, 589 USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_MDLM,
580 USB_CDC_PROTO_NONE), 590 USB_CDC_PROTO_NONE),
581 .driver_info = (unsigned long)&mbm_info, 591 .driver_info = (unsigned long)&wwan_info,
582 592
593}, {
594 /* Various Huawei modems with a network port like the UMG1831 */
595 .match_flags = USB_DEVICE_ID_MATCH_VENDOR
596 | USB_DEVICE_ID_MATCH_INT_INFO,
597 .idVendor = HUAWEI_VENDOR_ID,
598 .bInterfaceClass = USB_CLASS_COMM,
599 .bInterfaceSubClass = USB_CDC_SUBCLASS_ETHERNET,
600 .bInterfaceProtocol = 255,
601 .driver_info = (unsigned long)&wwan_info,
583}, 602},
584 { }, // END 603 { }, // END
585}; 604};
diff --git a/drivers/net/usb/cdc_ncm.c b/drivers/net/usb/cdc_ncm.c
index 7113168473cf..1033ef6476a4 100644
--- a/drivers/net/usb/cdc_ncm.c
+++ b/drivers/net/usb/cdc_ncm.c
@@ -54,13 +54,13 @@
54#include <linux/usb/usbnet.h> 54#include <linux/usb/usbnet.h>
55#include <linux/usb/cdc.h> 55#include <linux/usb/cdc.h>
56 56
57#define DRIVER_VERSION "7-Feb-2011" 57#define DRIVER_VERSION "23-Apr-2011"
58 58
59/* CDC NCM subclass 3.2.1 */ 59/* CDC NCM subclass 3.2.1 */
60#define USB_CDC_NCM_NDP16_LENGTH_MIN 0x10 60#define USB_CDC_NCM_NDP16_LENGTH_MIN 0x10
61 61
62/* Maximum NTB length */ 62/* Maximum NTB length */
63#define CDC_NCM_NTB_MAX_SIZE_TX 16384 /* bytes */ 63#define CDC_NCM_NTB_MAX_SIZE_TX (16384 + 4) /* bytes, must be short terminated */
64#define CDC_NCM_NTB_MAX_SIZE_RX 16384 /* bytes */ 64#define CDC_NCM_NTB_MAX_SIZE_RX 16384 /* bytes */
65 65
66/* Minimum value for MaxDatagramSize, ch. 6.2.9 */ 66/* Minimum value for MaxDatagramSize, ch. 6.2.9 */
@@ -1237,7 +1237,7 @@ static int cdc_ncm_manage_power(struct usbnet *dev, int status)
1237 1237
1238static const struct driver_info cdc_ncm_info = { 1238static const struct driver_info cdc_ncm_info = {
1239 .description = "CDC NCM", 1239 .description = "CDC NCM",
1240 .flags = FLAG_NO_SETINT | FLAG_MULTI_PACKET, 1240 .flags = FLAG_POINTTOPOINT | FLAG_NO_SETINT | FLAG_MULTI_PACKET,
1241 .bind = cdc_ncm_bind, 1241 .bind = cdc_ncm_bind,
1242 .unbind = cdc_ncm_unbind, 1242 .unbind = cdc_ncm_unbind,
1243 .check_connect = cdc_ncm_check_connect, 1243 .check_connect = cdc_ncm_check_connect,
diff --git a/drivers/net/usb/cdc_subset.c b/drivers/net/usb/cdc_subset.c
index ca39ace0b0eb..fc5f13d47ad9 100644
--- a/drivers/net/usb/cdc_subset.c
+++ b/drivers/net/usb/cdc_subset.c
@@ -89,6 +89,7 @@ static int always_connected (struct usbnet *dev)
89 89
90static const struct driver_info ali_m5632_info = { 90static const struct driver_info ali_m5632_info = {
91 .description = "ALi M5632", 91 .description = "ALi M5632",
92 .flags = FLAG_POINTTOPOINT,
92}; 93};
93 94
94#endif 95#endif
@@ -110,6 +111,7 @@ static const struct driver_info ali_m5632_info = {
110 111
111static const struct driver_info an2720_info = { 112static const struct driver_info an2720_info = {
112 .description = "AnchorChips/Cypress 2720", 113 .description = "AnchorChips/Cypress 2720",
114 .flags = FLAG_POINTTOPOINT,
113 // no reset available! 115 // no reset available!
114 // no check_connect available! 116 // no check_connect available!
115 117
@@ -132,6 +134,7 @@ static const struct driver_info an2720_info = {
132 134
133static const struct driver_info belkin_info = { 135static const struct driver_info belkin_info = {
134 .description = "Belkin, eTEK, or compatible", 136 .description = "Belkin, eTEK, or compatible",
137 .flags = FLAG_POINTTOPOINT,
135}; 138};
136 139
137#endif /* CONFIG_USB_BELKIN */ 140#endif /* CONFIG_USB_BELKIN */
@@ -157,6 +160,7 @@ static const struct driver_info belkin_info = {
157static const struct driver_info epson2888_info = { 160static const struct driver_info epson2888_info = {
158 .description = "Epson USB Device", 161 .description = "Epson USB Device",
159 .check_connect = always_connected, 162 .check_connect = always_connected,
163 .flags = FLAG_POINTTOPOINT,
160 164
161 .in = 4, .out = 3, 165 .in = 4, .out = 3,
162}; 166};
@@ -173,6 +177,7 @@ static const struct driver_info epson2888_info = {
173#define HAVE_HARDWARE 177#define HAVE_HARDWARE
174static const struct driver_info kc2190_info = { 178static const struct driver_info kc2190_info = {
175 .description = "KC Technology KC-190", 179 .description = "KC Technology KC-190",
180 .flags = FLAG_POINTTOPOINT,
176}; 181};
177#endif /* CONFIG_USB_KC2190 */ 182#endif /* CONFIG_USB_KC2190 */
178 183
@@ -200,16 +205,19 @@ static const struct driver_info kc2190_info = {
200static const struct driver_info linuxdev_info = { 205static const struct driver_info linuxdev_info = {
201 .description = "Linux Device", 206 .description = "Linux Device",
202 .check_connect = always_connected, 207 .check_connect = always_connected,
208 .flags = FLAG_POINTTOPOINT,
203}; 209};
204 210
205static const struct driver_info yopy_info = { 211static const struct driver_info yopy_info = {
206 .description = "Yopy", 212 .description = "Yopy",
207 .check_connect = always_connected, 213 .check_connect = always_connected,
214 .flags = FLAG_POINTTOPOINT,
208}; 215};
209 216
210static const struct driver_info blob_info = { 217static const struct driver_info blob_info = {
211 .description = "Boot Loader OBject", 218 .description = "Boot Loader OBject",
212 .check_connect = always_connected, 219 .check_connect = always_connected,
220 .flags = FLAG_POINTTOPOINT,
213}; 221};
214 222
215#endif /* CONFIG_USB_ARMLINUX */ 223#endif /* CONFIG_USB_ARMLINUX */
diff --git a/drivers/net/usb/gl620a.c b/drivers/net/usb/gl620a.c
index dcd57c37ef73..c4cfd1dea881 100644
--- a/drivers/net/usb/gl620a.c
+++ b/drivers/net/usb/gl620a.c
@@ -193,7 +193,7 @@ static int genelink_bind(struct usbnet *dev, struct usb_interface *intf)
193 193
194static const struct driver_info genelink_info = { 194static const struct driver_info genelink_info = {
195 .description = "Genesys GeneLink", 195 .description = "Genesys GeneLink",
196 .flags = FLAG_FRAMING_GL | FLAG_NO_SETINT, 196 .flags = FLAG_POINTTOPOINT | FLAG_FRAMING_GL | FLAG_NO_SETINT,
197 .bind = genelink_bind, 197 .bind = genelink_bind,
198 .rx_fixup = genelink_rx_fixup, 198 .rx_fixup = genelink_rx_fixup,
199 .tx_fixup = genelink_tx_fixup, 199 .tx_fixup = genelink_tx_fixup,
diff --git a/drivers/net/usb/ipheth.c b/drivers/net/usb/ipheth.c
index 7d42f9a2c068..81126ff85e05 100644
--- a/drivers/net/usb/ipheth.c
+++ b/drivers/net/usb/ipheth.c
@@ -65,6 +65,7 @@
65#define IPHETH_USBINTF_PROTO 1 65#define IPHETH_USBINTF_PROTO 1
66 66
67#define IPHETH_BUF_SIZE 1516 67#define IPHETH_BUF_SIZE 1516
68#define IPHETH_IP_ALIGN 2 /* padding at front of URB */
68#define IPHETH_TX_TIMEOUT (5 * HZ) 69#define IPHETH_TX_TIMEOUT (5 * HZ)
69 70
70#define IPHETH_INTFNUM 2 71#define IPHETH_INTFNUM 2
@@ -202,18 +203,21 @@ static void ipheth_rcvbulk_callback(struct urb *urb)
202 return; 203 return;
203 } 204 }
204 205
205 len = urb->actual_length; 206 if (urb->actual_length <= IPHETH_IP_ALIGN) {
206 buf = urb->transfer_buffer; 207 dev->net->stats.rx_length_errors++;
208 return;
209 }
210 len = urb->actual_length - IPHETH_IP_ALIGN;
211 buf = urb->transfer_buffer + IPHETH_IP_ALIGN;
207 212
208 skb = dev_alloc_skb(NET_IP_ALIGN + len); 213 skb = dev_alloc_skb(len);
209 if (!skb) { 214 if (!skb) {
210 err("%s: dev_alloc_skb: -ENOMEM", __func__); 215 err("%s: dev_alloc_skb: -ENOMEM", __func__);
211 dev->net->stats.rx_dropped++; 216 dev->net->stats.rx_dropped++;
212 return; 217 return;
213 } 218 }
214 219
215 skb_reserve(skb, NET_IP_ALIGN); 220 memcpy(skb_put(skb, len), buf, len);
216 memcpy(skb_put(skb, len), buf + NET_IP_ALIGN, len - NET_IP_ALIGN);
217 skb->dev = dev->net; 221 skb->dev = dev->net;
218 skb->protocol = eth_type_trans(skb, dev->net); 222 skb->protocol = eth_type_trans(skb, dev->net);
219 223
diff --git a/drivers/net/usb/kaweth.c b/drivers/net/usb/kaweth.c
index 7dc84971f26f..ad0298f9b5f9 100644
--- a/drivers/net/usb/kaweth.c
+++ b/drivers/net/usb/kaweth.c
@@ -1221,7 +1221,7 @@ static void kaweth_disconnect(struct usb_interface *intf)
1221 1221
1222 usb_set_intfdata(intf, NULL); 1222 usb_set_intfdata(intf, NULL);
1223 if (!kaweth) { 1223 if (!kaweth) {
1224 dev_warn(&intf->dev, "unregistering non-existant device\n"); 1224 dev_warn(&intf->dev, "unregistering non-existent device\n");
1225 return; 1225 return;
1226 } 1226 }
1227 netdev = kaweth->net; 1227 netdev = kaweth->net;
diff --git a/drivers/net/usb/lg-vl600.c b/drivers/net/usb/lg-vl600.c
new file mode 100644
index 000000000000..1d83ccfd7277
--- /dev/null
+++ b/drivers/net/usb/lg-vl600.c
@@ -0,0 +1,346 @@
1/*
2 * Ethernet interface part of the LG VL600 LTE modem (4G dongle)
3 *
4 * Copyright (C) 2011 Intel Corporation
5 * Author: Andrzej Zaborowski <balrogg@gmail.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21#include <linux/etherdevice.h>
22#include <linux/ethtool.h>
23#include <linux/mii.h>
24#include <linux/usb.h>
25#include <linux/usb/cdc.h>
26#include <linux/usb/usbnet.h>
27#include <linux/if_ether.h>
28#include <linux/if_arp.h>
29#include <linux/inetdevice.h>
30
31/*
32 * The device has a CDC ACM port for modem control (it claims to be
33 * CDC ACM anyway) and a CDC Ethernet port for actual network data.
34 * It will however ignore data on both ports that is not encapsulated
35 * in a specific way, any data returned is also encapsulated the same
36 * way. The headers don't seem to follow any popular standard.
37 *
38 * This driver adds and strips these headers from the ethernet frames
39 * sent/received from the CDC Ethernet port. The proprietary header
40 * replaces the standard ethernet header in a packet so only actual
41 * ethernet frames are allowed. The headers allow some form of
42 * multiplexing by using non standard values of the .h_proto field.
43 * Windows/Mac drivers do send a couple of such frames to the device
44 * during initialisation, with protocol set to 0x0906 or 0x0b06 and (what
45 * seems to be) a flag in the .dummy_flags. This doesn't seem necessary
46 * for modem operation but can possibly be used for GPS or other funcitons.
47 */
48
49struct vl600_frame_hdr {
50 __le32 len;
51 __le32 serial;
52 __le32 pkt_cnt;
53 __le32 dummy_flags;
54 __le32 dummy;
55 __le32 magic;
56} __attribute__((packed));
57
58struct vl600_pkt_hdr {
59 __le32 dummy[2];
60 __le32 len;
61 __be16 h_proto;
62} __attribute__((packed));
63
64struct vl600_state {
65 struct sk_buff *current_rx_buf;
66};
67
68static int vl600_bind(struct usbnet *dev, struct usb_interface *intf)
69{
70 int ret;
71 struct vl600_state *s = kzalloc(sizeof(struct vl600_state), GFP_KERNEL);
72
73 if (!s)
74 return -ENOMEM;
75
76 ret = usbnet_cdc_bind(dev, intf);
77 if (ret) {
78 kfree(s);
79 return ret;
80 }
81
82 dev->driver_priv = s;
83
84 /* ARP packets don't go through, but they're also of no use. The
85 * subnet has only two hosts anyway: us and the gateway / DHCP
86 * server (probably simulated by modem firmware or network operator)
87 * whose address changes everytime we connect to the intarwebz and
88 * who doesn't bother answering ARP requests either. So hardware
89 * addresses have no meaning, the destination and the source of every
90 * packet depend only on whether it is on the IN or OUT endpoint. */
91 dev->net->flags |= IFF_NOARP;
92
93 return ret;
94}
95
96static void vl600_unbind(struct usbnet *dev, struct usb_interface *intf)
97{
98 struct vl600_state *s = dev->driver_priv;
99
100 if (s->current_rx_buf)
101 dev_kfree_skb(s->current_rx_buf);
102
103 kfree(s);
104
105 return usbnet_cdc_unbind(dev, intf);
106}
107
108static int vl600_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
109{
110 struct vl600_frame_hdr *frame;
111 struct vl600_pkt_hdr *packet;
112 struct ethhdr *ethhdr;
113 int packet_len, count;
114 struct sk_buff *buf = skb;
115 struct sk_buff *clone;
116 struct vl600_state *s = dev->driver_priv;
117
118 /* Frame lengths are generally 4B multiplies but every couple of
119 * hours there's an odd number of bytes sized yet correct frame,
120 * so don't require this. */
121
122 /* Allow a packet (or multiple packets batched together) to be
123 * split across many frames. We don't allow a new batch to
124 * begin in the same frame another one is ending however, and no
125 * leading or trailing pad bytes. */
126 if (s->current_rx_buf) {
127 frame = (struct vl600_frame_hdr *) s->current_rx_buf->data;
128 if (skb->len + s->current_rx_buf->len >
129 le32_to_cpup(&frame->len)) {
130 netif_err(dev, ifup, dev->net, "Fragment too long\n");
131 dev->net->stats.rx_length_errors++;
132 goto error;
133 }
134
135 buf = s->current_rx_buf;
136 memcpy(skb_put(buf, skb->len), skb->data, skb->len);
137 } else if (skb->len < 4) {
138 netif_err(dev, ifup, dev->net, "Frame too short\n");
139 dev->net->stats.rx_length_errors++;
140 goto error;
141 }
142
143 frame = (struct vl600_frame_hdr *) buf->data;
144 /* NOTE: Should check that frame->magic == 0x53544448?
145 * Otherwise if we receive garbage at the beginning of the frame
146 * we may end up allocating a huge buffer and saving all the
147 * future incoming data into it. */
148
149 if (buf->len < sizeof(*frame) ||
150 buf->len != le32_to_cpup(&frame->len)) {
151 /* Save this fragment for later assembly */
152 if (s->current_rx_buf)
153 return 0;
154
155 s->current_rx_buf = skb_copy_expand(skb, 0,
156 le32_to_cpup(&frame->len), GFP_ATOMIC);
157 if (!s->current_rx_buf) {
158 netif_err(dev, ifup, dev->net, "Reserving %i bytes "
159 "for packet assembly failed.\n",
160 le32_to_cpup(&frame->len));
161 dev->net->stats.rx_errors++;
162 }
163
164 return 0;
165 }
166
167 count = le32_to_cpup(&frame->pkt_cnt);
168
169 skb_pull(buf, sizeof(*frame));
170
171 while (count--) {
172 if (buf->len < sizeof(*packet)) {
173 netif_err(dev, ifup, dev->net, "Packet too short\n");
174 goto error;
175 }
176
177 packet = (struct vl600_pkt_hdr *) buf->data;
178 packet_len = sizeof(*packet) + le32_to_cpup(&packet->len);
179 if (packet_len > buf->len) {
180 netif_err(dev, ifup, dev->net,
181 "Bad packet length stored in header\n");
182 goto error;
183 }
184
185 /* Packet header is same size as the ethernet header
186 * (sizeof(*packet) == sizeof(*ethhdr)), additionally
187 * the h_proto field is in the same place so we just leave it
188 * alone and fill in the remaining fields.
189 */
190 ethhdr = (struct ethhdr *) skb->data;
191 if (be16_to_cpup(&ethhdr->h_proto) == ETH_P_ARP &&
192 buf->len > 0x26) {
193 /* Copy the addresses from packet contents */
194 memcpy(ethhdr->h_source,
195 &buf->data[sizeof(*ethhdr) + 0x8],
196 ETH_ALEN);
197 memcpy(ethhdr->h_dest,
198 &buf->data[sizeof(*ethhdr) + 0x12],
199 ETH_ALEN);
200 } else {
201 memset(ethhdr->h_source, 0, ETH_ALEN);
202 memcpy(ethhdr->h_dest, dev->net->dev_addr, ETH_ALEN);
203 }
204
205 if (count) {
206 /* Not the last packet in this batch */
207 clone = skb_clone(buf, GFP_ATOMIC);
208 if (!clone)
209 goto error;
210
211 skb_trim(clone, packet_len);
212 usbnet_skb_return(dev, clone);
213
214 skb_pull(buf, (packet_len + 3) & ~3);
215 } else {
216 skb_trim(buf, packet_len);
217
218 if (s->current_rx_buf) {
219 usbnet_skb_return(dev, buf);
220 s->current_rx_buf = NULL;
221 return 0;
222 }
223
224 return 1;
225 }
226 }
227
228error:
229 if (s->current_rx_buf) {
230 dev_kfree_skb_any(s->current_rx_buf);
231 s->current_rx_buf = NULL;
232 }
233 dev->net->stats.rx_errors++;
234 return 0;
235}
236
237static struct sk_buff *vl600_tx_fixup(struct usbnet *dev,
238 struct sk_buff *skb, gfp_t flags)
239{
240 struct sk_buff *ret;
241 struct vl600_frame_hdr *frame;
242 struct vl600_pkt_hdr *packet;
243 static uint32_t serial = 1;
244 int orig_len = skb->len - sizeof(struct ethhdr);
245 int full_len = (skb->len + sizeof(struct vl600_frame_hdr) + 3) & ~3;
246
247 frame = (struct vl600_frame_hdr *) skb->data;
248 if (skb->len > sizeof(*frame) && skb->len == le32_to_cpup(&frame->len))
249 return skb; /* Already encapsulated? */
250
251 if (skb->len < sizeof(struct ethhdr))
252 /* Drop, device can only deal with ethernet packets */
253 return NULL;
254
255 if (!skb_cloned(skb)) {
256 int headroom = skb_headroom(skb);
257 int tailroom = skb_tailroom(skb);
258
259 if (tailroom >= full_len - skb->len - sizeof(*frame) &&
260 headroom >= sizeof(*frame))
261 /* There's enough head and tail room */
262 goto encapsulate;
263
264 if (headroom + tailroom + skb->len >= full_len) {
265 /* There's enough total room, just readjust */
266 skb->data = memmove(skb->head + sizeof(*frame),
267 skb->data, skb->len);
268 skb_set_tail_pointer(skb, skb->len);
269 goto encapsulate;
270 }
271 }
272
273 /* Alloc a new skb with the required size */
274 ret = skb_copy_expand(skb, sizeof(struct vl600_frame_hdr), full_len -
275 skb->len - sizeof(struct vl600_frame_hdr), flags);
276 dev_kfree_skb_any(skb);
277 if (!ret)
278 return ret;
279 skb = ret;
280
281encapsulate:
282 /* Packet header is same size as ethernet packet header
283 * (sizeof(*packet) == sizeof(struct ethhdr)), additionally the
284 * h_proto field is in the same place so we just leave it alone and
285 * overwrite the remaining fields.
286 */
287 packet = (struct vl600_pkt_hdr *) skb->data;
288 memset(&packet->dummy, 0, sizeof(packet->dummy));
289 packet->len = cpu_to_le32(orig_len);
290
291 frame = (struct vl600_frame_hdr *) skb_push(skb, sizeof(*frame));
292 memset(frame, 0, sizeof(*frame));
293 frame->len = cpu_to_le32(full_len);
294 frame->serial = cpu_to_le32(serial++);
295 frame->pkt_cnt = cpu_to_le32(1);
296
297 if (skb->len < full_len) /* Pad */
298 skb_put(skb, full_len - skb->len);
299
300 return skb;
301}
302
303static const struct driver_info vl600_info = {
304 .description = "LG VL600 modem",
305 .flags = FLAG_ETHER | FLAG_RX_ASSEMBLE,
306 .bind = vl600_bind,
307 .unbind = vl600_unbind,
308 .status = usbnet_cdc_status,
309 .rx_fixup = vl600_rx_fixup,
310 .tx_fixup = vl600_tx_fixup,
311};
312
313static const struct usb_device_id products[] = {
314 {
315 USB_DEVICE_AND_INTERFACE_INFO(0x1004, 0x61aa, USB_CLASS_COMM,
316 USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE),
317 .driver_info = (unsigned long) &vl600_info,
318 },
319 {}, /* End */
320};
321MODULE_DEVICE_TABLE(usb, products);
322
323static struct usb_driver lg_vl600_driver = {
324 .name = "lg-vl600",
325 .id_table = products,
326 .probe = usbnet_probe,
327 .disconnect = usbnet_disconnect,
328 .suspend = usbnet_suspend,
329 .resume = usbnet_resume,
330};
331
332static int __init vl600_init(void)
333{
334 return usb_register(&lg_vl600_driver);
335}
336module_init(vl600_init);
337
338static void __exit vl600_exit(void)
339{
340 usb_deregister(&lg_vl600_driver);
341}
342module_exit(vl600_exit);
343
344MODULE_AUTHOR("Anrzej Zaborowski");
345MODULE_DESCRIPTION("LG-VL600 modem's ethernet link");
346MODULE_LICENSE("GPL");
diff --git a/drivers/net/usb/net1080.c b/drivers/net/usb/net1080.c
index ba72a7281cb0..01db4602a39e 100644
--- a/drivers/net/usb/net1080.c
+++ b/drivers/net/usb/net1080.c
@@ -560,7 +560,7 @@ static int net1080_bind(struct usbnet *dev, struct usb_interface *intf)
560 560
561static const struct driver_info net1080_info = { 561static const struct driver_info net1080_info = {
562 .description = "NetChip TurboCONNECT", 562 .description = "NetChip TurboCONNECT",
563 .flags = FLAG_FRAMING_NC, 563 .flags = FLAG_POINTTOPOINT | FLAG_FRAMING_NC,
564 .bind = net1080_bind, 564 .bind = net1080_bind,
565 .reset = net1080_reset, 565 .reset = net1080_reset,
566 .check_connect = net1080_check_connect, 566 .check_connect = net1080_check_connect,
diff --git a/drivers/net/usb/plusb.c b/drivers/net/usb/plusb.c
index 08ad269f6b4e..823c53751307 100644
--- a/drivers/net/usb/plusb.c
+++ b/drivers/net/usb/plusb.c
@@ -96,7 +96,7 @@ static int pl_reset(struct usbnet *dev)
96 96
97static const struct driver_info prolific_info = { 97static const struct driver_info prolific_info = {
98 .description = "Prolific PL-2301/PL-2302", 98 .description = "Prolific PL-2301/PL-2302",
99 .flags = FLAG_NO_SETINT, 99 .flags = FLAG_POINTTOPOINT | FLAG_NO_SETINT,
100 /* some PL-2302 versions seem to fail usb_set_interface() */ 100 /* some PL-2302 versions seem to fail usb_set_interface() */
101 .reset = pl_reset, 101 .reset = pl_reset,
102}; 102};
diff --git a/drivers/net/usb/rndis_host.c b/drivers/net/usb/rndis_host.c
index dd8a4adf48ca..5994a25c56ac 100644
--- a/drivers/net/usb/rndis_host.c
+++ b/drivers/net/usb/rndis_host.c
@@ -573,7 +573,7 @@ EXPORT_SYMBOL_GPL(rndis_tx_fixup);
573 573
574static const struct driver_info rndis_info = { 574static const struct driver_info rndis_info = {
575 .description = "RNDIS device", 575 .description = "RNDIS device",
576 .flags = FLAG_ETHER | FLAG_FRAMING_RN | FLAG_NO_SETINT, 576 .flags = FLAG_ETHER | FLAG_POINTTOPOINT | FLAG_FRAMING_RN | FLAG_NO_SETINT,
577 .bind = rndis_bind, 577 .bind = rndis_bind,
578 .unbind = rndis_unbind, 578 .unbind = rndis_unbind,
579 .status = rndis_status, 579 .status = rndis_status,
diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c
index bc86f4b6ecc2..48d4efdb4959 100644
--- a/drivers/net/usb/smsc95xx.c
+++ b/drivers/net/usb/smsc95xx.c
@@ -49,6 +49,8 @@
49 49
50struct smsc95xx_priv { 50struct smsc95xx_priv {
51 u32 mac_cr; 51 u32 mac_cr;
52 u32 hash_hi;
53 u32 hash_lo;
52 spinlock_t mac_cr_lock; 54 spinlock_t mac_cr_lock;
53 bool use_tx_csum; 55 bool use_tx_csum;
54 bool use_rx_csum; 56 bool use_rx_csum;
@@ -370,10 +372,11 @@ static void smsc95xx_set_multicast(struct net_device *netdev)
370{ 372{
371 struct usbnet *dev = netdev_priv(netdev); 373 struct usbnet *dev = netdev_priv(netdev);
372 struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]); 374 struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]);
373 u32 hash_hi = 0;
374 u32 hash_lo = 0;
375 unsigned long flags; 375 unsigned long flags;
376 376
377 pdata->hash_hi = 0;
378 pdata->hash_lo = 0;
379
377 spin_lock_irqsave(&pdata->mac_cr_lock, flags); 380 spin_lock_irqsave(&pdata->mac_cr_lock, flags);
378 381
379 if (dev->net->flags & IFF_PROMISC) { 382 if (dev->net->flags & IFF_PROMISC) {
@@ -394,13 +397,13 @@ static void smsc95xx_set_multicast(struct net_device *netdev)
394 u32 bitnum = smsc95xx_hash(ha->addr); 397 u32 bitnum = smsc95xx_hash(ha->addr);
395 u32 mask = 0x01 << (bitnum & 0x1F); 398 u32 mask = 0x01 << (bitnum & 0x1F);
396 if (bitnum & 0x20) 399 if (bitnum & 0x20)
397 hash_hi |= mask; 400 pdata->hash_hi |= mask;
398 else 401 else
399 hash_lo |= mask; 402 pdata->hash_lo |= mask;
400 } 403 }
401 404
402 netif_dbg(dev, drv, dev->net, "HASHH=0x%08X, HASHL=0x%08X\n", 405 netif_dbg(dev, drv, dev->net, "HASHH=0x%08X, HASHL=0x%08X\n",
403 hash_hi, hash_lo); 406 pdata->hash_hi, pdata->hash_lo);
404 } else { 407 } else {
405 netif_dbg(dev, drv, dev->net, "receive own packets only\n"); 408 netif_dbg(dev, drv, dev->net, "receive own packets only\n");
406 pdata->mac_cr &= 409 pdata->mac_cr &=
@@ -410,8 +413,8 @@ static void smsc95xx_set_multicast(struct net_device *netdev)
410 spin_unlock_irqrestore(&pdata->mac_cr_lock, flags); 413 spin_unlock_irqrestore(&pdata->mac_cr_lock, flags);
411 414
412 /* Initiate async writes, as we can't wait for completion here */ 415 /* Initiate async writes, as we can't wait for completion here */
413 smsc95xx_write_reg_async(dev, HASHH, &hash_hi); 416 smsc95xx_write_reg_async(dev, HASHH, &pdata->hash_hi);
414 smsc95xx_write_reg_async(dev, HASHL, &hash_lo); 417 smsc95xx_write_reg_async(dev, HASHL, &pdata->hash_lo);
415 smsc95xx_write_reg_async(dev, MAC_CR, &pdata->mac_cr); 418 smsc95xx_write_reg_async(dev, MAC_CR, &pdata->mac_cr);
416} 419}
417 420
@@ -727,7 +730,7 @@ static int smsc95xx_phy_initialize(struct usbnet *dev)
727 msleep(10); 730 msleep(10);
728 bmcr = smsc95xx_mdio_read(dev->net, dev->mii.phy_id, MII_BMCR); 731 bmcr = smsc95xx_mdio_read(dev->net, dev->mii.phy_id, MII_BMCR);
729 timeout++; 732 timeout++;
730 } while ((bmcr & MII_BMCR) && (timeout < 100)); 733 } while ((bmcr & BMCR_RESET) && (timeout < 100));
731 734
732 if (timeout >= 100) { 735 if (timeout >= 100) {
733 netdev_warn(dev->net, "timeout on PHY Reset"); 736 netdev_warn(dev->net, "timeout on PHY Reset");
@@ -1310,6 +1313,21 @@ static const struct usb_device_id products[] = {
1310 USB_DEVICE(0x0424, 0x9909), 1313 USB_DEVICE(0x0424, 0x9909),
1311 .driver_info = (unsigned long) &smsc95xx_info, 1314 .driver_info = (unsigned long) &smsc95xx_info,
1312 }, 1315 },
1316 {
1317 /* SMSC LAN9530 USB Ethernet Device */
1318 USB_DEVICE(0x0424, 0x9530),
1319 .driver_info = (unsigned long) &smsc95xx_info,
1320 },
1321 {
1322 /* SMSC LAN9730 USB Ethernet Device */
1323 USB_DEVICE(0x0424, 0x9730),
1324 .driver_info = (unsigned long) &smsc95xx_info,
1325 },
1326 {
1327 /* SMSC LAN89530 USB Ethernet Device */
1328 USB_DEVICE(0x0424, 0x9E08),
1329 .driver_info = (unsigned long) &smsc95xx_info,
1330 },
1313 { }, /* END */ 1331 { }, /* END */
1314}; 1332};
1315MODULE_DEVICE_TABLE(usb, products); 1333MODULE_DEVICE_TABLE(usb, products);
diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c
index 95c41d56631c..9ab439d144ed 100644
--- a/drivers/net/usb/usbnet.c
+++ b/drivers/net/usb/usbnet.c
@@ -387,8 +387,12 @@ static int rx_submit (struct usbnet *dev, struct urb *urb, gfp_t flags)
387static inline void rx_process (struct usbnet *dev, struct sk_buff *skb) 387static inline void rx_process (struct usbnet *dev, struct sk_buff *skb)
388{ 388{
389 if (dev->driver_info->rx_fixup && 389 if (dev->driver_info->rx_fixup &&
390 !dev->driver_info->rx_fixup (dev, skb)) 390 !dev->driver_info->rx_fixup (dev, skb)) {
391 goto error; 391 /* With RX_ASSEMBLE, rx_fixup() must update counters */
392 if (!(dev->driver_info->flags & FLAG_RX_ASSEMBLE))
393 dev->net->stats.rx_errors++;
394 goto done;
395 }
392 // else network stack removes extra byte if we forced a short packet 396 // else network stack removes extra byte if we forced a short packet
393 397
394 if (skb->len) { 398 if (skb->len) {
@@ -401,8 +405,8 @@ static inline void rx_process (struct usbnet *dev, struct sk_buff *skb)
401 } 405 }
402 406
403 netif_dbg(dev, rx_err, dev->net, "drop\n"); 407 netif_dbg(dev, rx_err, dev->net, "drop\n");
404error:
405 dev->net->stats.rx_errors++; 408 dev->net->stats.rx_errors++;
409done:
406 skb_queue_tail(&dev->done, skb); 410 skb_queue_tail(&dev->done, skb);
407} 411}
408 412
@@ -641,6 +645,7 @@ int usbnet_stop (struct net_device *net)
641 struct driver_info *info = dev->driver_info; 645 struct driver_info *info = dev->driver_info;
642 int retval; 646 int retval;
643 647
648 clear_bit(EVENT_DEV_OPEN, &dev->flags);
644 netif_stop_queue (net); 649 netif_stop_queue (net);
645 650
646 netif_info(dev, ifdown, dev->net, 651 netif_info(dev, ifdown, dev->net,
@@ -732,6 +737,7 @@ int usbnet_open (struct net_device *net)
732 } 737 }
733 } 738 }
734 739
740 set_bit(EVENT_DEV_OPEN, &dev->flags);
735 netif_start_queue (net); 741 netif_start_queue (net);
736 netif_info(dev, ifup, dev->net, 742 netif_info(dev, ifup, dev->net,
737 "open: enable queueing (rx %d, tx %d) mtu %d %s framing\n", 743 "open: enable queueing (rx %d, tx %d) mtu %d %s framing\n",
@@ -1255,6 +1261,9 @@ void usbnet_disconnect (struct usb_interface *intf)
1255 if (dev->driver_info->unbind) 1261 if (dev->driver_info->unbind)
1256 dev->driver_info->unbind (dev, intf); 1262 dev->driver_info->unbind (dev, intf);
1257 1263
1264 usb_kill_urb(dev->interrupt);
1265 usb_free_urb(dev->interrupt);
1266
1258 free_netdev(net); 1267 free_netdev(net);
1259 usb_put_dev (xdev); 1268 usb_put_dev (xdev);
1260} 1269}
@@ -1376,7 +1385,8 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod)
1376 // else "eth%d" when there's reasonable doubt. userspace 1385 // else "eth%d" when there's reasonable doubt. userspace
1377 // can rename the link if it knows better. 1386 // can rename the link if it knows better.
1378 if ((dev->driver_info->flags & FLAG_ETHER) != 0 && 1387 if ((dev->driver_info->flags & FLAG_ETHER) != 0 &&
1379 (net->dev_addr [0] & 0x02) == 0) 1388 ((dev->driver_info->flags & FLAG_POINTTOPOINT) == 0 ||
1389 (net->dev_addr [0] & 0x02) == 0))
1380 strcpy (net->name, "eth%d"); 1390 strcpy (net->name, "eth%d");
1381 /* WLAN devices should always be named "wlan%d" */ 1391 /* WLAN devices should always be named "wlan%d" */
1382 if ((dev->driver_info->flags & FLAG_WLAN) != 0) 1392 if ((dev->driver_info->flags & FLAG_WLAN) != 0)
@@ -1493,6 +1503,10 @@ int usbnet_resume (struct usb_interface *intf)
1493 int retval; 1503 int retval;
1494 1504
1495 if (!--dev->suspend_count) { 1505 if (!--dev->suspend_count) {
1506 /* resume interrupt URBs */
1507 if (dev->interrupt && test_bit(EVENT_DEV_OPEN, &dev->flags))
1508 usb_submit_urb(dev->interrupt, GFP_NOIO);
1509
1496 spin_lock_irq(&dev->txq.lock); 1510 spin_lock_irq(&dev->txq.lock);
1497 while ((res = usb_get_from_anchor(&dev->deferred))) { 1511 while ((res = usb_get_from_anchor(&dev->deferred))) {
1498 1512
@@ -1511,9 +1525,12 @@ int usbnet_resume (struct usb_interface *intf)
1511 smp_mb(); 1525 smp_mb();
1512 clear_bit(EVENT_DEV_ASLEEP, &dev->flags); 1526 clear_bit(EVENT_DEV_ASLEEP, &dev->flags);
1513 spin_unlock_irq(&dev->txq.lock); 1527 spin_unlock_irq(&dev->txq.lock);
1514 if (!(dev->txq.qlen >= TX_QLEN(dev))) 1528
1515 netif_start_queue(dev->net); 1529 if (test_bit(EVENT_DEV_OPEN, &dev->flags)) {
1516 tasklet_schedule (&dev->bh); 1530 if (!(dev->txq.qlen >= TX_QLEN(dev)))
1531 netif_start_queue(dev->net);
1532 tasklet_schedule (&dev->bh);
1533 }
1517 } 1534 }
1518 return 0; 1535 return 0;
1519} 1536}
diff --git a/drivers/net/usb/zaurus.c b/drivers/net/usb/zaurus.c
index 3eb0b167b5b4..241756e0e86f 100644
--- a/drivers/net/usb/zaurus.c
+++ b/drivers/net/usb/zaurus.c
@@ -102,7 +102,7 @@ static int always_connected (struct usbnet *dev)
102 102
103static const struct driver_info zaurus_sl5x00_info = { 103static const struct driver_info zaurus_sl5x00_info = {
104 .description = "Sharp Zaurus SL-5x00", 104 .description = "Sharp Zaurus SL-5x00",
105 .flags = FLAG_FRAMING_Z, 105 .flags = FLAG_POINTTOPOINT | FLAG_FRAMING_Z,
106 .check_connect = always_connected, 106 .check_connect = always_connected,
107 .bind = zaurus_bind, 107 .bind = zaurus_bind,
108 .unbind = usbnet_cdc_unbind, 108 .unbind = usbnet_cdc_unbind,
@@ -112,7 +112,7 @@ static const struct driver_info zaurus_sl5x00_info = {
112 112
113static const struct driver_info zaurus_pxa_info = { 113static const struct driver_info zaurus_pxa_info = {
114 .description = "Sharp Zaurus, PXA-2xx based", 114 .description = "Sharp Zaurus, PXA-2xx based",
115 .flags = FLAG_FRAMING_Z, 115 .flags = FLAG_POINTTOPOINT | FLAG_FRAMING_Z,
116 .check_connect = always_connected, 116 .check_connect = always_connected,
117 .bind = zaurus_bind, 117 .bind = zaurus_bind,
118 .unbind = usbnet_cdc_unbind, 118 .unbind = usbnet_cdc_unbind,
@@ -122,7 +122,7 @@ static const struct driver_info zaurus_pxa_info = {
122 122
123static const struct driver_info olympus_mxl_info = { 123static const struct driver_info olympus_mxl_info = {
124 .description = "Olympus R1000", 124 .description = "Olympus R1000",
125 .flags = FLAG_FRAMING_Z, 125 .flags = FLAG_POINTTOPOINT | FLAG_FRAMING_Z,
126 .check_connect = always_connected, 126 .check_connect = always_connected,
127 .bind = zaurus_bind, 127 .bind = zaurus_bind,
128 .unbind = usbnet_cdc_unbind, 128 .unbind = usbnet_cdc_unbind,
@@ -258,7 +258,7 @@ bad_desc:
258 258
259static const struct driver_info bogus_mdlm_info = { 259static const struct driver_info bogus_mdlm_info = {
260 .description = "pseudo-MDLM (BLAN) device", 260 .description = "pseudo-MDLM (BLAN) device",
261 .flags = FLAG_FRAMING_Z, 261 .flags = FLAG_POINTTOPOINT | FLAG_FRAMING_Z,
262 .check_connect = always_connected, 262 .check_connect = always_connected,
263 .tx_fixup = zaurus_tx_fixup, 263 .tx_fixup = zaurus_tx_fixup,
264 .bind = blan_mdlm_bind, 264 .bind = blan_mdlm_bind,