Skip to content

Commit bbc8d92

Browse files
bmorkdavem330
authored andcommitted
net: cdc_ncm: add Huawei devices
A number of Huawei 3G and LTE modems implement a CDC NCM function, including the necessary functional descriptors, but using a non standard interface layout and class/subclass/protocol codes. These devices can be handled by this driver with only a minor change to the probing logic, allowing a single combined control and data interface. This works because the devices - include a CDC Union descriptor labelling the combined interface as both master and slave, and - have an alternate setting #1 for the bulk endpoints on the combined interface. The 3G/LTE network connection is managed by vendor specific AT commands on a serial function in the same composite device. Handling the managment function is out of the scope of this driver. It will be handled by an appropriate USB serial driver. Reported-and-Tested-by: Olof Ermis <[email protected]> Reported-and-Tested-by: Tommy Cheng <[email protected]> Signed-off-by: Bjørn Mork <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 7702745 commit bbc8d92

File tree

1 file changed

+18
-4
lines changed

1 file changed

+18
-4
lines changed

drivers/net/usb/cdc_ncm.c

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -540,10 +540,12 @@ static int cdc_ncm_bind(struct usbnet *dev, struct usb_interface *intf)
540540
(ctx->ether_desc == NULL) || (ctx->control != intf))
541541
goto error;
542542

543-
/* claim interfaces, if any */
544-
temp = usb_driver_claim_interface(driver, ctx->data, dev);
545-
if (temp)
546-
goto error;
543+
/* claim data interface, if different from control */
544+
if (ctx->data != ctx->control) {
545+
temp = usb_driver_claim_interface(driver, ctx->data, dev);
546+
if (temp)
547+
goto error;
548+
}
547549

548550
iface_no = ctx->data->cur_altsetting->desc.bInterfaceNumber;
549551

@@ -623,6 +625,10 @@ static void cdc_ncm_unbind(struct usbnet *dev, struct usb_interface *intf)
623625

624626
tasklet_kill(&ctx->bh);
625627

628+
/* handle devices with combined control and data interface */
629+
if (ctx->control == ctx->data)
630+
ctx->data = NULL;
631+
626632
/* disconnect master --> disconnect slave */
627633
if (intf == ctx->control && ctx->data) {
628634
usb_set_intfdata(ctx->data, NULL);
@@ -1245,6 +1251,14 @@ static const struct usb_device_id cdc_devs[] = {
12451251
.driver_info = (unsigned long) &wwan_info,
12461252
},
12471253

1254+
/* Huawei NCM devices disguised as vendor specific */
1255+
{ USB_VENDOR_AND_INTERFACE_INFO(0x12d1, 0xff, 0x02, 0x16),
1256+
.driver_info = (unsigned long)&wwan_info,
1257+
},
1258+
{ USB_VENDOR_AND_INTERFACE_INFO(0x12d1, 0xff, 0x02, 0x46),
1259+
.driver_info = (unsigned long)&wwan_info,
1260+
},
1261+
12481262
/* Generic CDC-NCM devices */
12491263
{ USB_INTERFACE_INFO(USB_CLASS_COMM,
12501264
USB_CDC_SUBCLASS_NCM, USB_CDC_PROTO_NONE),

0 commit comments

Comments
 (0)