diff options
Diffstat (limited to 'drivers/net/usb/cdc_ncm.c')
-rw-r--r-- | drivers/net/usb/cdc_ncm.c | 28 |
1 files changed, 28 insertions, 0 deletions
diff --git a/drivers/net/usb/cdc_ncm.c b/drivers/net/usb/cdc_ncm.c index d103a1d4fb36..8f572b9f3625 100644 --- a/drivers/net/usb/cdc_ncm.c +++ b/drivers/net/usb/cdc_ncm.c | |||
@@ -768,8 +768,10 @@ int cdc_ncm_bind_common(struct usbnet *dev, struct usb_interface *intf, u8 data_ | |||
768 | u8 *buf; | 768 | u8 *buf; |
769 | int len; | 769 | int len; |
770 | int temp; | 770 | int temp; |
771 | int err; | ||
771 | u8 iface_no; | 772 | u8 iface_no; |
772 | struct usb_cdc_parsed_header hdr; | 773 | struct usb_cdc_parsed_header hdr; |
774 | u16 curr_ntb_format; | ||
773 | 775 | ||
774 | ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); | 776 | ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); |
775 | if (!ctx) | 777 | if (!ctx) |
@@ -874,6 +876,32 @@ int cdc_ncm_bind_common(struct usbnet *dev, struct usb_interface *intf, u8 data_ | |||
874 | goto error2; | 876 | goto error2; |
875 | } | 877 | } |
876 | 878 | ||
879 | /* | ||
880 | * Some Huawei devices have been observed to come out of reset in NDP32 mode. | ||
881 | * Let's check if this is the case, and set the device to NDP16 mode again if | ||
882 | * needed. | ||
883 | */ | ||
884 | if (ctx->drvflags & CDC_NCM_FLAG_RESET_NTB16) { | ||
885 | err = usbnet_read_cmd(dev, USB_CDC_GET_NTB_FORMAT, | ||
886 | USB_TYPE_CLASS | USB_DIR_IN | USB_RECIP_INTERFACE, | ||
887 | 0, iface_no, &curr_ntb_format, 2); | ||
888 | if (err < 0) { | ||
889 | goto error2; | ||
890 | } | ||
891 | |||
892 | if (curr_ntb_format == USB_CDC_NCM_NTB32_FORMAT) { | ||
893 | dev_info(&intf->dev, "resetting NTB format to 16-bit"); | ||
894 | err = usbnet_write_cmd(dev, USB_CDC_SET_NTB_FORMAT, | ||
895 | USB_TYPE_CLASS | USB_DIR_OUT | ||
896 | | USB_RECIP_INTERFACE, | ||
897 | USB_CDC_NCM_NTB16_FORMAT, | ||
898 | iface_no, NULL, 0); | ||
899 | |||
900 | if (err < 0) | ||
901 | goto error2; | ||
902 | } | ||
903 | } | ||
904 | |||
877 | cdc_ncm_find_endpoints(dev, ctx->data); | 905 | cdc_ncm_find_endpoints(dev, ctx->data); |
878 | cdc_ncm_find_endpoints(dev, ctx->control); | 906 | cdc_ncm_find_endpoints(dev, ctx->control); |
879 | if (!dev->in || !dev->out || !dev->status) { | 907 | if (!dev->in || !dev->out || !dev->status) { |