Skip to content

Commit

Permalink
cdc_ncm: Set NTB format again after altsetting switch for Huawei devices
Browse files Browse the repository at this point in the history
Some firmwares in Huawei E3372H devices have been observed to switch back
to NTB 32-bit format after altsetting switch.
This patch implements a driver flag to check for the device settings and
set NTB format to 16-bit again if needed.
The flag has been activated for devices controlled by the huawei_cdc_ncm.c
driver.

V1->V2:
- fixed broken error checks
- some corrections to the commit message
V2->V3:
- variable name changes, to clarify what's happening
- check (and possibly set) the NTB format later in the common bind code path

Signed-off-by: Enrico Mioso <mrkiko.rs@gmail.com>
Reported-and-tested-by: Christian Panton <christian@panton.org>
Reviewed-by: Bjørn Mork <bjorn@mork.no>
CC: Bjørn Mork <bjorn@mork.no>
CC: Christian Panton <christian@panton.org>
CC: linux-usb@vger.kernel.org
CC: netdev@vger.kernel.org
CC: Oliver Neukum <oliver@neukum.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
mrkiko authored and davem330 committed Jul 14, 2017
1 parent 457839e commit 2b02c20
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 0 deletions.
28 changes: 28 additions & 0 deletions drivers/net/usb/cdc_ncm.c
Original file line number Diff line number Diff line change
Expand Up @@ -768,8 +768,10 @@ int cdc_ncm_bind_common(struct usbnet *dev, struct usb_interface *intf, u8 data_
u8 *buf;
int len;
int temp;
int err;
u8 iface_no;
struct usb_cdc_parsed_header hdr;
u16 curr_ntb_format;

ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
if (!ctx)
Expand Down Expand Up @@ -874,6 +876,32 @@ int cdc_ncm_bind_common(struct usbnet *dev, struct usb_interface *intf, u8 data_
goto error2;
}

/*
* Some Huawei devices have been observed to come out of reset in NDP32 mode.
* Let's check if this is the case, and set the device to NDP16 mode again if
* needed.
*/
if (ctx->drvflags & CDC_NCM_FLAG_RESET_NTB16) {
err = usbnet_read_cmd(dev, USB_CDC_GET_NTB_FORMAT,
USB_TYPE_CLASS | USB_DIR_IN | USB_RECIP_INTERFACE,
0, iface_no, &curr_ntb_format, 2);
if (err < 0) {
goto error2;
}

if (curr_ntb_format == USB_CDC_NCM_NTB32_FORMAT) {
dev_info(&intf->dev, "resetting NTB format to 16-bit");
err = usbnet_write_cmd(dev, USB_CDC_SET_NTB_FORMAT,
USB_TYPE_CLASS | USB_DIR_OUT
| USB_RECIP_INTERFACE,
USB_CDC_NCM_NTB16_FORMAT,
iface_no, NULL, 0);

if (err < 0)
goto error2;
}
}

cdc_ncm_find_endpoints(dev, ctx->data);
cdc_ncm_find_endpoints(dev, ctx->control);
if (!dev->in || !dev->out || !dev->status) {
Expand Down
6 changes: 6 additions & 0 deletions drivers/net/usb/huawei_cdc_ncm.c
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,12 @@ static int huawei_cdc_ncm_bind(struct usbnet *usbnet_dev,
* be at the end of the frame.
*/
drvflags |= CDC_NCM_FLAG_NDP_TO_END;

/* Additionally, it has been reported that some Huawei E3372H devices, with
* firmware version 21.318.01.00.541, come out of reset in NTB32 format mode, hence
* needing to be set to the NTB16 one again.
*/
drvflags |= CDC_NCM_FLAG_RESET_NTB16;
ret = cdc_ncm_bind_common(usbnet_dev, intf, 1, drvflags);
if (ret)
goto err;
Expand Down
1 change: 1 addition & 0 deletions include/linux/usb/cdc_ncm.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@
/* Driver flags */
#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_FLAG_RESET_NTB16 0x08 /* set NDP16 one more time after altsetting switch */

#define cdc_ncm_comm_intf_is_mbim(x) ((x)->desc.bInterfaceSubClass == USB_CDC_SUBCLASS_MBIM && \
(x)->desc.bInterfaceProtocol == USB_CDC_PROTO_NONE)
Expand Down

0 comments on commit 2b02c20

Please sign in to comment.