Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

NET: usb: cdc_mbim: add quirk for supporting Telit LE922A

Telit LE922A MBIM based composition does not work properly
with altsetting toggle done in cdc_ncm_bind_common.

This patch adds CDC_MBIM_FLAG_AVOID_ALTSETTING_TOGGLE quirk
to avoid this procedure that, instead, is mandatory for
other modems.

Signed-off-by: Daniele Palmas <dnlplm@gmail.com>
Reviewed-by: Bjørn Mork <bjorn@mork.no>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Daniele Palmas and committed by
David S. Miller
7b8076ce ec988ad7

+32 -6
+21
drivers/net/usb/cdc_mbim.c
··· 602 602 .data = CDC_NCM_FLAG_NDP_TO_END, 603 603 }; 604 604 605 + /* Some modems (e.g. Telit LE922A6) do not work properly with altsetting 606 + * toggle done in cdc_ncm_bind_common. CDC_MBIM_FLAG_AVOID_ALTSETTING_TOGGLE 607 + * flag is used to avoid this procedure. 608 + */ 609 + static const struct driver_info cdc_mbim_info_avoid_altsetting_toggle = { 610 + .description = "CDC MBIM", 611 + .flags = FLAG_NO_SETINT | FLAG_MULTI_PACKET | FLAG_WWAN, 612 + .bind = cdc_mbim_bind, 613 + .unbind = cdc_mbim_unbind, 614 + .manage_power = cdc_mbim_manage_power, 615 + .rx_fixup = cdc_mbim_rx_fixup, 616 + .tx_fixup = cdc_mbim_tx_fixup, 617 + .data = CDC_MBIM_FLAG_AVOID_ALTSETTING_TOGGLE, 618 + }; 619 + 605 620 static const struct usb_device_id mbim_devs[] = { 606 621 /* This duplicate NCM entry is intentional. MBIM devices can 607 622 * be disguised as NCM by default, and this is necessary to ··· 641 626 { USB_VENDOR_AND_INTERFACE_INFO(0x12d1, USB_CLASS_COMM, USB_CDC_SUBCLASS_MBIM, USB_CDC_PROTO_NONE), 642 627 .driver_info = (unsigned long)&cdc_mbim_info_ndp_to_end, 643 628 }, 629 + 630 + /* Telit LE922A6 in MBIM composition */ 631 + { USB_DEVICE_AND_INTERFACE_INFO(0x1bc7, 0x1041, USB_CLASS_COMM, USB_CDC_SUBCLASS_MBIM, USB_CDC_PROTO_NONE), 632 + .driver_info = (unsigned long)&cdc_mbim_info_avoid_altsetting_toggle, 633 + }, 634 + 644 635 /* default entry */ 645 636 { USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_MBIM, USB_CDC_PROTO_NONE), 646 637 .driver_info = (unsigned long)&cdc_mbim_info_zlp,
+9 -5
drivers/net/usb/cdc_ncm.c
··· 839 839 840 840 iface_no = ctx->data->cur_altsetting->desc.bInterfaceNumber; 841 841 842 + /* Device-specific flags */ 843 + ctx->drvflags = drvflags; 844 + 842 845 /* Reset data interface. Some devices will not reset properly 843 846 * unless they are configured first. Toggle the altsetting to 844 - * force a reset 847 + * force a reset. 848 + * Some other devices do not work properly with this procedure 849 + * that can be avoided using quirk CDC_MBIM_FLAG_AVOID_ALTSETTING_TOGGLE 845 850 */ 846 - usb_set_interface(dev->udev, iface_no, data_altsetting); 851 + if (!(ctx->drvflags & CDC_MBIM_FLAG_AVOID_ALTSETTING_TOGGLE)) 852 + usb_set_interface(dev->udev, iface_no, data_altsetting); 853 + 847 854 temp = usb_set_interface(dev->udev, iface_no, 0); 848 855 if (temp) { 849 856 dev_dbg(&intf->dev, "set interface failed\n"); ··· 896 889 897 890 /* finish setting up the device specific data */ 898 891 cdc_ncm_setup(dev); 899 - 900 - /* Device-specific flags */ 901 - ctx->drvflags = drvflags; 902 892 903 893 /* Allocate the delayed NDP if needed. */ 904 894 if (ctx->drvflags & CDC_NCM_FLAG_NDP_TO_END) {
+2 -1
include/linux/usb/cdc_ncm.h
··· 81 81 #define CDC_NCM_TIMER_INTERVAL_MAX (U32_MAX / NSEC_PER_USEC) 82 82 83 83 /* Driver flags */ 84 - #define CDC_NCM_FLAG_NDP_TO_END 0x02 /* NDP is placed at end of frame */ 84 + #define CDC_NCM_FLAG_NDP_TO_END 0x02 /* NDP is placed at end of frame */ 85 + #define CDC_MBIM_FLAG_AVOID_ALTSETTING_TOGGLE 0x04 /* Avoid altsetting toggle during init */ 85 86 86 87 #define cdc_ncm_comm_intf_is_mbim(x) ((x)->desc.bInterfaceSubClass == USB_CDC_SUBCLASS_MBIM && \ 87 88 (x)->desc.bInterfaceProtocol == USB_CDC_PROTO_NONE)