From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751272AbaCPGtN (ORCPT ); Sun, 16 Mar 2014 02:49:13 -0400 Received: from mail-vc0-f202.google.com ([209.85.220.202]:58687 "EHLO mail-vc0-f202.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750973AbaCPGtM (ORCPT ); Sun, 16 Mar 2014 02:49:12 -0400 From: Ben Chan To: linux-kernel@vger.kernel.org, linux-usb@vger.kernel.org, netdev@vger.kernel.org, Oliver Neukum Cc: Greg Kroah-Hartman , =?UTF-8?q?Bj=C3=B8rn=20Mork?= , Greg Suarez Subject: [PATCH 2/2] net: cdc_ncm: respect operator preferred MTU reported by MBIM Date: Sat, 15 Mar 2014 23:49:10 -0700 Message-Id: <1394952550-9308-2-git-send-email-benchan@chromium.org> X-Mailer: git-send-email 1.9.0.279.gdc9e3eb In-Reply-To: <1394952550-9308-1-git-send-email-benchan@chromium.org> References: <1394952550-9308-1-git-send-email-benchan@chromium.org> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org According to "Universal Serial Bus Communications Class Subclass Specification for Mobile Broadband Interface Model, Revision 1.0, Errata-1" published by USB-IF, the wMTU field of the MBIM extended functional descriptor indicates the operator preferred MTU for IP data streams. This patch modifies cdc_ncm_setup to ensure that the MTU value set on the usbnet device does not exceed the operator preferred MTU indicated by wMTU if the MBIM device exposes a MBIM extended functional descriptor. Signed-off-by: Ben Chan --- drivers/net/usb/cdc_ncm.c | 15 +++++++++++++++ include/linux/usb/cdc_ncm.h | 1 + 2 files changed, 16 insertions(+) diff --git a/drivers/net/usb/cdc_ncm.c b/drivers/net/usb/cdc_ncm.c index dbff290..0b036ed 100644 --- a/drivers/net/usb/cdc_ncm.c +++ b/drivers/net/usb/cdc_ncm.c @@ -261,6 +261,13 @@ out: /* set MTU to max supported by the device if necessary */ if (dev->net->mtu > ctx->max_datagram_size - eth_hlen) dev->net->mtu = ctx->max_datagram_size - eth_hlen; + + /* do not exceed operater preferred MTU */ + if (ctx->mbim_extended_desc && + ctx->mbim_extended_desc->wMTU != 0 && + dev->net->mtu > ctx->mbim_extended_desc->wMTU) + dev->net->mtu = ctx->mbim_extended_desc->wMTU; + return 0; } @@ -399,6 +406,14 @@ int cdc_ncm_bind_common(struct usbnet *dev, struct usb_interface *intf, u8 data_ ctx->mbim_desc = (const struct usb_cdc_mbim_desc *)buf; break; + case USB_CDC_MBIM_EXTENDED_TYPE: + if (buf[0] < sizeof(*(ctx->mbim_extended_desc))) + break; + + ctx->mbim_extended_desc = + (const struct usb_cdc_mbim_extended_desc *)buf; + break; + default: break; } diff --git a/include/linux/usb/cdc_ncm.h b/include/linux/usb/cdc_ncm.h index c3fa807..bdf05fb 100644 --- a/include/linux/usb/cdc_ncm.h +++ b/include/linux/usb/cdc_ncm.h @@ -93,6 +93,7 @@ struct cdc_ncm_ctx { const struct usb_cdc_ncm_desc *func_desc; const struct usb_cdc_mbim_desc *mbim_desc; + const struct usb_cdc_mbim_extended_desc *mbim_extended_desc; const struct usb_cdc_ether_desc *ether_desc; struct usb_interface *control; -- 1.9.0.279.gdc9e3eb