Commit 7b8076ce authored by Daniele Palmas's avatar Daniele Palmas Committed by David S. Miller

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: default avatarDaniele Palmas <dnlplm@gmail.com>
Reviewed-by: default avatarBjørn Mork <bjorn@mork.no>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent ec988ad7
...@@ -602,6 +602,21 @@ static const struct driver_info cdc_mbim_info_ndp_to_end = { ...@@ -602,6 +602,21 @@ static const struct driver_info cdc_mbim_info_ndp_to_end = {
.data = CDC_NCM_FLAG_NDP_TO_END, .data = CDC_NCM_FLAG_NDP_TO_END,
}; };
/* Some modems (e.g. Telit LE922A6) do not work properly with altsetting
* toggle done in cdc_ncm_bind_common. CDC_MBIM_FLAG_AVOID_ALTSETTING_TOGGLE
* flag is used to avoid this procedure.
*/
static const struct driver_info cdc_mbim_info_avoid_altsetting_toggle = {
.description = "CDC MBIM",
.flags = FLAG_NO_SETINT | FLAG_MULTI_PACKET | FLAG_WWAN,
.bind = cdc_mbim_bind,
.unbind = cdc_mbim_unbind,
.manage_power = cdc_mbim_manage_power,
.rx_fixup = cdc_mbim_rx_fixup,
.tx_fixup = cdc_mbim_tx_fixup,
.data = CDC_MBIM_FLAG_AVOID_ALTSETTING_TOGGLE,
};
static const struct usb_device_id mbim_devs[] = { static const struct usb_device_id mbim_devs[] = {
/* This duplicate NCM entry is intentional. MBIM devices can /* This duplicate NCM entry is intentional. MBIM devices can
* be disguised as NCM by default, and this is necessary to * be disguised as NCM by default, and this is necessary to
...@@ -626,6 +641,12 @@ static const struct usb_device_id mbim_devs[] = { ...@@ -626,6 +641,12 @@ static const struct usb_device_id mbim_devs[] = {
{ USB_VENDOR_AND_INTERFACE_INFO(0x12d1, USB_CLASS_COMM, USB_CDC_SUBCLASS_MBIM, USB_CDC_PROTO_NONE), { USB_VENDOR_AND_INTERFACE_INFO(0x12d1, USB_CLASS_COMM, USB_CDC_SUBCLASS_MBIM, USB_CDC_PROTO_NONE),
.driver_info = (unsigned long)&cdc_mbim_info_ndp_to_end, .driver_info = (unsigned long)&cdc_mbim_info_ndp_to_end,
}, },
/* Telit LE922A6 in MBIM composition */
{ USB_DEVICE_AND_INTERFACE_INFO(0x1bc7, 0x1041, USB_CLASS_COMM, USB_CDC_SUBCLASS_MBIM, USB_CDC_PROTO_NONE),
.driver_info = (unsigned long)&cdc_mbim_info_avoid_altsetting_toggle,
},
/* default entry */ /* default entry */
{ USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_MBIM, USB_CDC_PROTO_NONE), { USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_MBIM, USB_CDC_PROTO_NONE),
.driver_info = (unsigned long)&cdc_mbim_info_zlp, .driver_info = (unsigned long)&cdc_mbim_info_zlp,
......
...@@ -839,11 +839,18 @@ int cdc_ncm_bind_common(struct usbnet *dev, struct usb_interface *intf, u8 data_ ...@@ -839,11 +839,18 @@ int cdc_ncm_bind_common(struct usbnet *dev, struct usb_interface *intf, u8 data_
iface_no = ctx->data->cur_altsetting->desc.bInterfaceNumber; iface_no = ctx->data->cur_altsetting->desc.bInterfaceNumber;
/* Device-specific flags */
ctx->drvflags = drvflags;
/* Reset data interface. Some devices will not reset properly /* Reset data interface. Some devices will not reset properly
* unless they are configured first. Toggle the altsetting to * unless they are configured first. Toggle the altsetting to
* force a reset * force a reset.
* Some other devices do not work properly with this procedure
* that can be avoided using quirk CDC_MBIM_FLAG_AVOID_ALTSETTING_TOGGLE
*/ */
usb_set_interface(dev->udev, iface_no, data_altsetting); if (!(ctx->drvflags & CDC_MBIM_FLAG_AVOID_ALTSETTING_TOGGLE))
usb_set_interface(dev->udev, iface_no, data_altsetting);
temp = usb_set_interface(dev->udev, iface_no, 0); temp = usb_set_interface(dev->udev, iface_no, 0);
if (temp) { if (temp) {
dev_dbg(&intf->dev, "set interface failed\n"); dev_dbg(&intf->dev, "set interface failed\n");
...@@ -890,9 +897,6 @@ int cdc_ncm_bind_common(struct usbnet *dev, struct usb_interface *intf, u8 data_ ...@@ -890,9 +897,6 @@ int cdc_ncm_bind_common(struct usbnet *dev, struct usb_interface *intf, u8 data_
/* finish setting up the device specific data */ /* finish setting up the device specific data */
cdc_ncm_setup(dev); cdc_ncm_setup(dev);
/* Device-specific flags */
ctx->drvflags = drvflags;
/* Allocate the delayed NDP if needed. */ /* Allocate the delayed NDP if needed. */
if (ctx->drvflags & CDC_NCM_FLAG_NDP_TO_END) { if (ctx->drvflags & CDC_NCM_FLAG_NDP_TO_END) {
ctx->delayed_ndp16 = kzalloc(ctx->max_ndp_size, GFP_KERNEL); ctx->delayed_ndp16 = kzalloc(ctx->max_ndp_size, GFP_KERNEL);
......
...@@ -81,7 +81,8 @@ ...@@ -81,7 +81,8 @@
#define CDC_NCM_TIMER_INTERVAL_MAX (U32_MAX / NSEC_PER_USEC) #define CDC_NCM_TIMER_INTERVAL_MAX (U32_MAX / NSEC_PER_USEC)
/* Driver flags */ /* Driver flags */
#define CDC_NCM_FLAG_NDP_TO_END 0x02 /* NDP is placed at end of frame */ #define CDC_NCM_FLAG_NDP_TO_END 0x02 /* NDP is placed at end of frame */
#define CDC_MBIM_FLAG_AVOID_ALTSETTING_TOGGLE 0x04 /* Avoid altsetting toggle during init */
#define cdc_ncm_comm_intf_is_mbim(x) ((x)->desc.bInterfaceSubClass == USB_CDC_SUBCLASS_MBIM && \ #define cdc_ncm_comm_intf_is_mbim(x) ((x)->desc.bInterfaceSubClass == USB_CDC_SUBCLASS_MBIM && \
(x)->desc.bInterfaceProtocol == USB_CDC_PROTO_NONE) (x)->desc.bInterfaceProtocol == USB_CDC_PROTO_NONE)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment