From patchwork Wed Nov 23 12:36:46 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniele Palmas X-Patchwork-Id: 698200 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3tP20Z4fY0z9t2n for ; Wed, 23 Nov 2016 23:37:18 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="TmVRYdyW"; dkim-atps=neutral Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S936004AbcKWMhN (ORCPT ); Wed, 23 Nov 2016 07:37:13 -0500 Received: from mail-wj0-f193.google.com ([209.85.210.193]:34198 "EHLO mail-wj0-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S934685AbcKWMhK (ORCPT ); Wed, 23 Nov 2016 07:37:10 -0500 Received: by mail-wj0-f193.google.com with SMTP id xy5so957190wjc.1; Wed, 23 Nov 2016 04:37:09 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=C6C/2xP/XemoB0zfyakRB/HYLwDKwG+Epwha0SzvdQ4=; b=TmVRYdyWJZbYp5Go7qLAQcECHQXxQN//q68M/2HDXvv0iCw7HFaQOU+3KbxurlmXIp +VyusBQ2qau3sDpb70fKYkl91pSVZ9K+KzqVY/U/BeMIFqm5WvI6cCaGFs9V//Qi4RyG nqo5Jk/f6BDvGjR6Myq0Gt8Xyl+QfS4FyJKwQpVWsPzUz1bDT4HhU+ylEwsB5uyy/+2J 2NmytqTYhwTY/5GIfYDmY6aQpdcB8O9e5VKldfQxv8Y6FUu7xiUIMa9yE0iJV5s2eyGB mFJuSvPhdBGzE+QKqGbI/XVV97cPdllmPbcNzHNnYachOHxp7Eqo5swCZQC9qf+N/ZuE t1NA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=C6C/2xP/XemoB0zfyakRB/HYLwDKwG+Epwha0SzvdQ4=; b=NSv3uu5hRnidaR7FZCVJHQkvuBkTDu1Wg8pxB2sAfbf0qsnJ/fZvefBKlW2SMeMSxd A+jwxuQCddTab5WPppp1tAcusnV2YsUUdvbFbDfsjOEeDxOqE5SQX0uwK3YglO9V2xHj hoU6qmAhegxjT4d0TYMLNEdmLHbCjmKjI3N109HT0RAG17bL3cADflYH9UbXCoEXbjE1 7es7zpXdKMnJdEbBxhAtHBZ1XlQM20HdTo5+xL2MjFQOhePRwfMWoabN3GEm2LPfAHm3 1toQUdDTHuJ9d8/NpnrqJkl9+DsS+5yQ9QT6gwUlIZETMVWuCRAkBAngS/NozK4HUMJz u+rg== X-Gm-Message-State: AKaTC01MZUlke2pbt2MASX5miB6ZtKMBLLpAjhx3yfwkMnCxUtaMOJMCJnttHdYTQpIBNg== X-Received: by 10.194.56.234 with SMTP id d10mr3380283wjq.78.1479904628611; Wed, 23 Nov 2016 04:37:08 -0800 (PST) Received: from localhost.localdomain ([5.92.219.103]) by smtp.gmail.com with ESMTPSA id f3sm2590303wmf.10.2016.11.23.04.37.07 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 23 Nov 2016 04:37:08 -0800 (PST) From: Daniele Palmas To: =?UTF-8?q?Bj=C3=B8rn=20Mork?= , Oliver Neukum Cc: linux-usb@vger.kernel.org, netdev@vger.kernel.org, Daniele Palmas Subject: [PATCH 1/1] NET: usb: cdc_ncm: adding MBIM RESET_FUNCTION request and modifying ncm bind common code Date: Wed, 23 Nov 2016 13:36:46 +0100 Message-Id: <1479904606-30647-2-git-send-email-dnlplm@gmail.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1479904606-30647-1-git-send-email-dnlplm@gmail.com> References: <1479904606-30647-1-git-send-email-dnlplm@gmail.com> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Some latest QC based modems seem not to properly accept altsetting toggling in cdc_ncm_bind_common, making them to fail. The workaround was to introduce an empirically decided pause to avoid the failure. This patch introduces a different approach: for MBIM devices, instead of toggling interfaces, the MBIM class-specific request code RESET_FUNCTION is used in order to reset the function to its initial state, removing the need for the pause. Signed-off-by: Daniele Palmas --- drivers/net/usb/cdc_ncm.c | 39 +++++++++++++++++++++++++++------------ include/uapi/linux/usb/cdc.h | 1 + 2 files changed, 28 insertions(+), 12 deletions(-) diff --git a/drivers/net/usb/cdc_ncm.c b/drivers/net/usb/cdc_ncm.c index 877c951..e8a7a76 100644 --- a/drivers/net/usb/cdc_ncm.c +++ b/drivers/net/usb/cdc_ncm.c @@ -498,6 +498,22 @@ static int cdc_ncm_init(struct usbnet *dev) return err; /* GET_NTB_PARAMETERS is required */ } + /* Some modems (e.g. Telit LE922A6) need to reset the MBIM function + * or they will fail to work properly. + * For details on RESET_FUNCTION request see document + * "USB Communication Class Subclass Specification for MBIM" + * RESET_FUNCTION should be harmless for all the other MBIM modems + */ + if (cdc_ncm_comm_intf_is_mbim(ctx->control->cur_altsetting)) { + err = usbnet_write_cmd(dev, USB_CDC_RESET_FUNCTION, + USB_TYPE_CLASS | USB_DIR_OUT + | USB_RECIP_INTERFACE, + 0, iface_no, NULL, 0); + if (err < 0) { + dev_err(&dev->intf->dev, "failed RESET_FUNCTION\n"); + } + } + /* set CRC Mode */ if (cdc_ncm_flags(dev) & USB_CDC_NCM_NCAP_CRC_MODE) { dev_dbg(&dev->intf->dev, "Setting CRC mode off\n"); @@ -842,25 +858,24 @@ int cdc_ncm_bind_common(struct usbnet *dev, struct usb_interface *intf, u8 data_ /* Reset data interface. Some devices will not reset properly * unless they are configured first. Toggle the altsetting to * force a reset + * This is applied only to ncm devices, since it has been verified + * to cause issues with some MBIM modems (e.g. Telit LE922A6). + * MBIM devices reset is achieved using MBIM request RESET_FUNCTION + * in cdc_ncm_init */ - usb_set_interface(dev->udev, iface_no, data_altsetting); - temp = usb_set_interface(dev->udev, iface_no, 0); - if (temp) { - dev_dbg(&intf->dev, "set interface failed\n"); - goto error2; + if (!cdc_ncm_comm_intf_is_mbim(intf->cur_altsetting)) { + usb_set_interface(dev->udev, iface_no, data_altsetting); + temp = usb_set_interface(dev->udev, iface_no, 0); + if (temp) { + dev_dbg(&intf->dev, "set interface failed\n"); + goto error2; + } } /* initialize basic device settings */ if (cdc_ncm_init(dev)) goto error2; - /* Some firmwares need a pause here or they will silently fail - * to set up the interface properly. This value was decided - * empirically on a Sierra Wireless MC7455 running 02.08.02.00 - * firmware. - */ - usleep_range(10000, 20000); - /* configure data interface */ temp = usb_set_interface(dev->udev, iface_no, data_altsetting); if (temp) { diff --git a/include/uapi/linux/usb/cdc.h b/include/uapi/linux/usb/cdc.h index e2bc417..30258fb 100644 --- a/include/uapi/linux/usb/cdc.h +++ b/include/uapi/linux/usb/cdc.h @@ -231,6 +231,7 @@ struct usb_cdc_mbim_extended_desc { #define USB_CDC_SEND_ENCAPSULATED_COMMAND 0x00 #define USB_CDC_GET_ENCAPSULATED_RESPONSE 0x01 +#define USB_CDC_RESET_FUNCTION 0x05 #define USB_CDC_REQ_SET_LINE_CODING 0x20 #define USB_CDC_REQ_GET_LINE_CODING 0x21 #define USB_CDC_REQ_SET_CONTROL_LINE_STATE 0x22