Skip to content

Commit

Permalink
net/usb: Ethernet quirks for the LG-VL600 4G modem
Browse files Browse the repository at this point in the history
This adds a driver for the CDC Ethernet part of this modem.  The
device's ID is blacklisted in cdc_ether.c and is white-listed in
this new driver because of the quirks needed to make it useful.
The modem's firmware exposes a CDC ACM port for modem control and a
CDC Ethernet port for network data.  The descriptors look fine but
both ports actually are some sort of multiplexers requiring non-
standard headers added/removed from every packet or they get
ignored.  All information is based on a usb traffic log from a
Windows machine.

On the Verizon 4G network I've seen speeds up to 1.1MB/s so far with
this driver, a speed-o-meter site reports 16.2Mbps/10.5Mbps.
Userspace scripts are required to talk to the CDC ACM port.

Signed-off-by: Andrzej Zaborowski <balrogg@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Andrzej Zaborowski authored and David S. Miller committed Mar 30, 2011
1 parent d005a09 commit 7a635ea
Show file tree
Hide file tree
Showing 6 changed files with 387 additions and 9 deletions.
15 changes: 15 additions & 0 deletions drivers/net/usb/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -433,4 +433,19 @@ config USB_SIERRA_NET
To compile this driver as a module, choose M here: the
module will be called sierra_net.

config USB_VL600
tristate "LG VL600 modem dongle"
depends on USB_NET_CDCETHER
select USB_ACM
help
Select this if you want to use an LG Electronics 4G/LTE usb modem
called VL600. This driver only handles the ethernet
interface exposed by the modem firmware. To establish a connection
you will first need a userspace program that sends the right
command to the modem through its CDC ACM port, and most
likely also a DHCP client. See this thread about using the
4G modem from Verizon:

http://ubuntuforums.org/showpost.php?p=10589647&postcount=17

endmenu
1 change: 1 addition & 0 deletions drivers/net/usb/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,5 @@ obj-$(CONFIG_USB_IPHETH) += ipheth.o
obj-$(CONFIG_USB_SIERRA_NET) += sierra_net.o
obj-$(CONFIG_USB_NET_CX82310_ETH) += cx82310_eth.o
obj-$(CONFIG_USB_NET_CDC_NCM) += cdc_ncm.o
obj-$(CONFIG_USB_VL600) += lg-vl600.o

21 changes: 15 additions & 6 deletions drivers/net/usb/cdc_ether.c
Original file line number Diff line number Diff line change
Expand Up @@ -378,7 +378,7 @@ static void dumpspeed(struct usbnet *dev, __le32 *speeds)
__le32_to_cpu(speeds[1]) / 1000);
}

static void cdc_status(struct usbnet *dev, struct urb *urb)
void usbnet_cdc_status(struct usbnet *dev, struct urb *urb)
{
struct usb_cdc_notification *event;

Expand Down Expand Up @@ -418,8 +418,9 @@ static void cdc_status(struct usbnet *dev, struct urb *urb)
break;
}
}
EXPORT_SYMBOL_GPL(usbnet_cdc_status);

static int cdc_bind(struct usbnet *dev, struct usb_interface *intf)
int usbnet_cdc_bind(struct usbnet *dev, struct usb_interface *intf)
{
int status;
struct cdc_state *info = (void *) &dev->data;
Expand All @@ -441,6 +442,7 @@ static int cdc_bind(struct usbnet *dev, struct usb_interface *intf)
*/
return 0;
}
EXPORT_SYMBOL_GPL(usbnet_cdc_bind);

static int cdc_manage_power(struct usbnet *dev, int on)
{
Expand All @@ -452,18 +454,18 @@ static const struct driver_info cdc_info = {
.description = "CDC Ethernet Device",
.flags = FLAG_ETHER,
// .check_connect = cdc_check_connect,
.bind = cdc_bind,
.bind = usbnet_cdc_bind,
.unbind = usbnet_cdc_unbind,
.status = cdc_status,
.status = usbnet_cdc_status,
.manage_power = cdc_manage_power,
};

static const struct driver_info mbm_info = {
.description = "Mobile Broadband Network Device",
.flags = FLAG_WWAN,
.bind = cdc_bind,
.bind = usbnet_cdc_bind,
.unbind = usbnet_cdc_unbind,
.status = cdc_status,
.status = usbnet_cdc_status,
.manage_power = cdc_manage_power,
};

Expand Down Expand Up @@ -560,6 +562,13 @@ static const struct usb_device_id products [] = {
.driver_info = 0,
},

/* LG Electronics VL600 wants additional headers on every frame */
{
USB_DEVICE_AND_INTERFACE_INFO(0x1004, 0x61aa, USB_CLASS_COMM,
USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE),
.driver_info = 0,
},

/*
* WHITELIST!!!
*
Expand Down
Loading

0 comments on commit 7a635ea

Please sign in to comment.