From patchwork Wed Nov 30 18:42:16 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kristian Evensen X-Patchwork-Id: 701119 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 3tTTn54N6sz9t0G for ; Thu, 1 Dec 2016 05:42:49 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="pSvmtcmc"; dkim-atps=neutral Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1758751AbcK3Smh (ORCPT ); Wed, 30 Nov 2016 13:42:37 -0500 Received: from mail-lf0-f65.google.com ([209.85.215.65]:35626 "EHLO mail-lf0-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1757704AbcK3Sme (ORCPT ); Wed, 30 Nov 2016 13:42:34 -0500 Received: by mail-lf0-f65.google.com with SMTP id p100so16726124lfg.2; Wed, 30 Nov 2016 10:42:32 -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; bh=r1jG6gfVxnzyNtQQ7VIH0wdoa4eRtZa+n0QAKlPqd0M=; b=pSvmtcmcr7ir05WJ3rx1CRbBNN9SneVzA266T5rA9NKb88BsXogfYkG4MvDfevmAal IeNd9rG+L4vSc0xYmb9zbmo4PFJePEdRTuyy57JxpfYfhNglYvfBotgCgdkPIjQhINu1 1DShrnFZPXi7Rd+rP5+FLwl1QKFM5CsZ1/BvgRWY881xamX30PbNGbhorot/IuK3izP6 rCceiyfGA/m8Hopm3vcJJGLQgXbHt+EhtQEl4lMFxJ2BAEeHvD3WzI27ktccB9TzY+2Q iUxrtInE6Rbx+R9oKUjyzRfANwIoAGcRdUx/jHKo1Wog7PoRVDSBVZIJAum3jeguKyR7 h7wQ== 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; bh=r1jG6gfVxnzyNtQQ7VIH0wdoa4eRtZa+n0QAKlPqd0M=; b=gOryTjgqjfgIHzMabuRhpYdL8UZJ7rv+j9lfkdogizc/71KKqGxlgxroPvBEhPWyJu 6VWAvixJSUv81S0tbE3eOnlCaiF108zaRUc4feBlwHILoOfZE1aCr94XUB5nfOI40N+Z LK3hefcDfCZv6UCPenOanAm4DA10ezjYz8P3mHp6u0StVOmMk2KyKDYymdrbUKqwnIn6 wN8OQaDtq0Rew2i9jI2FgmWw4FGHzHow9IbaS0UH0wx+OwNE4IFeAXTbd6QGh822Z42G Ac0Pl3TDNZbDljH1kKm9EyxXkRmF6FrIiqz/ue1y23ESXtJ34SNso0pyMV+t8KZh7fZU 5XqQ== X-Gm-Message-State: AKaTC01bIao9KPdUd1Z9GrRrY5hfUzzchlGkkDnbE/Mor3EP4u99DBnPyPeu9P7k3bK0Qg== X-Received: by 10.25.21.27 with SMTP id l27mr13605111lfi.163.1480531351654; Wed, 30 Nov 2016 10:42:31 -0800 (PST) Received: from localhost.localdomain ([77.88.71.153]) by smtp.gmail.com with ESMTPSA id d79sm14644585lfd.46.2016.11.30.10.42.30 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 30 Nov 2016 10:42:30 -0800 (PST) From: Kristian Evensen To: oliver@neukum.org, linux-usb@vger.kernel.org, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, henning.schild@siemens.com Cc: Kristian Evensen Subject: [PATCH net] cdc_ether: Fix handling connection notification Date: Wed, 30 Nov 2016 19:42:16 +0100 Message-Id: <20161130184216.4224-1-kristian.evensen@gmail.com> X-Mailer: git-send-email 2.9.3 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Commit bfe9b9d2df66 ("cdc_ether: Improve ZTE MF823/831/910 handling") introduced a work-around in usbnet_cdc_status() for devices that exported cdc carrier on twice on connect. Before the commit, this behavior caused the link state to be incorrect. It was assumed that all CDC Ethernet devices would either export this behavior, or send one off and then one on notification (which seems to be the default behavior). Unfortunately, it turns out multiple devices sends a connection notification multiple times per second (via an interrupt), even when connection state does not change. This has been observed with several different USB LAN dongles (at least), for example 13b1:0041 (Linksys). After bfe9b9d2df66, the link state has been set as down and then up for each notification. This has caused a flood of Netlink NEWLINK messages and syslog to be flooded with messages similar to: cdc_ether 2-1:2.0 eth1: kevent 12 may have been dropped This commit fixes the behavior by reverting usbnet_cdc_status() to how it was before bfe9b9d2df66. The work-around has been moved to a separate status-function which is only called when a known, affect device is detected. Fixes: bfe9b9d2df66 ("cdc_ether: Improve ZTE MF823/831/910 handling") Reported-by: Henning Schild Signed-off-by: Kristian Evensen --- drivers/net/usb/cdc_ether.c | 38 +++++++++++++++++++++++++++++++------- 1 file changed, 31 insertions(+), 7 deletions(-) diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c index 45e5e43..8c628ea 100644 --- a/drivers/net/usb/cdc_ether.c +++ b/drivers/net/usb/cdc_ether.c @@ -388,12 +388,6 @@ void usbnet_cdc_status(struct usbnet *dev, struct urb *urb) case USB_CDC_NOTIFY_NETWORK_CONNECTION: netif_dbg(dev, timer, dev->net, "CDC: carrier %s\n", event->wValue ? "on" : "off"); - - /* Work-around for devices with broken off-notifications */ - if (event->wValue && - !test_bit(__LINK_STATE_NOCARRIER, &dev->net->state)) - usbnet_link_change(dev, 0, 0); - usbnet_link_change(dev, !!event->wValue, 0); break; case USB_CDC_NOTIFY_SPEED_CHANGE: /* tx/rx rates */ @@ -466,6 +460,36 @@ static int usbnet_cdc_zte_rx_fixup(struct usbnet *dev, struct sk_buff *skb) return 1; } +/* Ensure correct link state + * + * Some devices (ZTE MF823/831/910) export two carrier on notifications when + * connected. This causes the link state to be incorrect. Work around this by + * always setting the state to off, then on. + */ +void usbnet_cdc_zte_status(struct usbnet *dev, struct urb *urb) +{ + struct usb_cdc_notification *event; + + if (urb->actual_length < sizeof(*event)) + return; + + event = urb->transfer_buffer; + + if (event->bNotificationType != USB_CDC_NOTIFY_NETWORK_CONNECTION) { + usbnet_cdc_status(dev, urb); + return; + } + + netif_dbg(dev, timer, dev->net, "CDC: carrier %s\n", + event->wValue ? "on" : "off"); + + if (event->wValue && + !test_bit(__LINK_STATE_NOCARRIER, &dev->net->state)) + usbnet_link_change(dev, 0, 0); + + usbnet_link_change(dev, !!event->wValue, 0); +} + static const struct driver_info cdc_info = { .description = "CDC Ethernet Device", .flags = FLAG_ETHER | FLAG_POINTTOPOINT, @@ -481,7 +505,7 @@ static const struct driver_info zte_cdc_info = { .flags = FLAG_ETHER | FLAG_POINTTOPOINT, .bind = usbnet_cdc_zte_bind, .unbind = usbnet_cdc_unbind, - .status = usbnet_cdc_status, + .status = usbnet_cdc_zte_status, .set_rx_mode = usbnet_cdc_update_filter, .manage_power = usbnet_manage_power, .rx_fixup = usbnet_cdc_zte_rx_fixup,