rndis_host: support Novatel Verizon USB730L
authorAleksander Morgado <aleksander@aleksander.es>
Wed, 27 Sep 2017 21:31:03 +0000 (23:31 +0200)
committerDavid S. Miller <davem@davemloft.net>
Tue, 3 Oct 2017 21:30:46 +0000 (14:30 -0700)
Treat the ef/04/01 interface class/subclass/protocol combination used
by the Novatel Verizon USB730L (1410:9030) as a possible RNDIS
interface.

 T:  Bus=01 Lev=02 Prnt=02 Port=01 Cnt=02 Dev#= 17 Spd=480 MxCh= 0
 D:  Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs=  3
 P:  Vendor=1410 ProdID=9030 Rev=03.10
 S:  Manufacturer=Novatel Wireless
 S:  Product=MiFi USB730L
 S:  SerialNumber=0123456789ABCDEF
 C:  #Ifs= 3 Cfg#= 1 Atr=80 MxPwr=500mA
 I:  If#= 0 Alt= 0 #EPs= 1 Cls=ef(misc ) Sub=04 Prot=01 Driver=rndis_host
 I:  If#= 1 Alt= 0 #EPs= 2 Cls=0a(data ) Sub=00 Prot=00 Driver=rndis_host
 I:  If#= 2 Alt= 0 #EPs= 1 Cls=03(HID  ) Sub=00 Prot=00 Driver=usbhid

Once the network interface is brought up, the user just needs to run a
DHCP client to get IP address and routing setup.

As a side note, other Novatel Verizon USB730L models with the same
vid:pid end up exposing a standard ECM interface which doesn't require
any other kernel update to make it work.

Signed-off-by: Aleksander Morgado <aleksander@aleksander.es>
Reviewed-by: Bjørn Mork <bjorn@mork.no>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/usb/cdc_ether.c
drivers/net/usb/rndis_host.c

index 677a85360db15a7c3733f5006479c2150f36dab6..29c7e2ec0dcbe0a8ef158d80f0e3c6b21be8abf7 100644 (file)
@@ -54,11 +54,19 @@ static int is_wireless_rndis(struct usb_interface_descriptor *desc)
                desc->bInterfaceProtocol == 3);
 }
 
+static int is_novatel_rndis(struct usb_interface_descriptor *desc)
+{
+       return (desc->bInterfaceClass == USB_CLASS_MISC &&
+               desc->bInterfaceSubClass == 4 &&
+               desc->bInterfaceProtocol == 1);
+}
+
 #else
 
 #define is_rndis(desc)         0
 #define is_activesync(desc)    0
 #define is_wireless_rndis(desc)        0
+#define is_novatel_rndis(desc) 0
 
 #endif
 
@@ -150,7 +158,8 @@ int usbnet_generic_cdc_bind(struct usbnet *dev, struct usb_interface *intf)
         */
        rndis = (is_rndis(&intf->cur_altsetting->desc) ||
                 is_activesync(&intf->cur_altsetting->desc) ||
-                is_wireless_rndis(&intf->cur_altsetting->desc));
+                is_wireless_rndis(&intf->cur_altsetting->desc) ||
+                is_novatel_rndis(&intf->cur_altsetting->desc));
 
        memset(info, 0, sizeof(*info));
        info->control = intf;
index a151f267aebb9c47312f724729e4c2755cb7512b..b807c91abe1da94fc16c7eca39c0de3a1e2070a3 100644 (file)
@@ -632,6 +632,10 @@ static const struct usb_device_id  products [] = {
        /* RNDIS for tethering */
        USB_INTERFACE_INFO(USB_CLASS_WIRELESS_CONTROLLER, 1, 3),
        .driver_info = (unsigned long) &rndis_info,
+}, {
+       /* Novatel Verizon USB730L */
+       USB_INTERFACE_INFO(USB_CLASS_MISC, 4, 1),
+       .driver_info = (unsigned long) &rndis_info,
 },
        { },            // END
 };