Received: by 2002:ad5:474a:0:0:0:0:0 with SMTP id i10csp3316484imu; Sun, 11 Nov 2018 12:13:07 -0800 (PST) X-Google-Smtp-Source: AJdET5fD5o6Gng8Hz/Eliqt+Z1733ZAS8zOaFS1Xrm6EvHsjNzP5s1xYywRE+hIKOFA6DCZxaYv+ X-Received: by 2002:a17:902:6e08:: with SMTP id u8-v6mr17191971plk.64.1541967187112; Sun, 11 Nov 2018 12:13:07 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1541967187; cv=none; d=google.com; s=arc-20160816; b=zEnodQMj2fOOOpek/CKXEA/uDkXLbmcbOZcdOLUELSLVrDn+4zz6ki0qY0L65UePGt 23sHbVjmmKxvbBYVbiLD/RMF/S61sbbaP5Z3FOyk6eYccUOH2jF+VfUPAbi531uX4oL0 zFAnUVL5W+zMDE7UCCHILu+FhWLMoXCA+QobFQvcP0H8+lK8G9PLS1/B1JED9/MJYFri 8fDyk2SRoh1/xD/SoEzl7FJbDi8YEPf075uUzd6AEu9J1q2lkW0Enanx/yipsOtiYD21 IGN9eUMUSEngWJRTDedv3tzNvAhpYj0ymGb+2BoMJJn/6fMajNLf6G8flOLP+Ni5Ssrn kmYQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:in-reply-to:subject:message-id:date:cc:to :from:mime-version:content-transfer-encoding:content-disposition; bh=gHi1eRL8a8xyREplkwEOs89yaYxjYki0/hfTJIrmHAo=; b=niRhzlGwfIOZPhprPcosY+gROgfbQIqB/cc/sfY8ubft8TlivxZQi4I00QlmlxmLJe 2hFYarTZJTW0pAq6Wu5baiCqe/LliT/tw0nG92TCNnavi5WrvZF4kkdW+Ri2xj/U6Edm b6yGzCOyjVcj0ZWdU/5OXzRa9ZbmM2XfnIvQ8zPJPogfUWvsYhV9WNhFHdJP7CjG1H3m ytZDx8ggnLJ9Ih7QXYzt4zGuinK4/73jgPT87FHpeq+zbhQUL057T/dhWXlrzpccLhpK g2I0ZQbCDl8es6+rYnOOxqHx3yrspDTyklKS923Xfo+66p3fDBOy8IBbC8B/+uW5pYGh zD5A== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id a2si14480804pgm.154.2018.11.11.12.12.51; Sun, 11 Nov 2018 12:13:07 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731346AbeKLGBg (ORCPT + 99 others); Mon, 12 Nov 2018 01:01:36 -0500 Received: from shadbolt.e.decadent.org.uk ([88.96.1.126]:52544 "EHLO shadbolt.e.decadent.org.uk" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727101AbeKLGBg (ORCPT ); Mon, 12 Nov 2018 01:01:36 -0500 Received: from [192.168.4.242] (helo=deadeye) by shadbolt.decadent.org.uk with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.89) (envelope-from ) id 1gLvst-0000lM-Gi; Sun, 11 Nov 2018 19:59:03 +0000 Received: from ben by deadeye with local (Exim 4.91) (envelope-from ) id 1gLvsV-0001fx-FU; Sun, 11 Nov 2018 19:58:39 +0000 Content-Type: text/plain; charset="UTF-8" Content-Disposition: inline Content-Transfer-Encoding: 8bit MIME-Version: 1.0 From: Ben Hutchings To: linux-kernel@vger.kernel.org, stable@vger.kernel.org CC: akpm@linux-foundation.org, "David S. Miller" , "Yuiko Oshino" Date: Sun, 11 Nov 2018 19:49:05 +0000 Message-ID: X-Mailer: LinuxStableQueue (scripts by bwh) Subject: [PATCH 3.16 227/366] smsc75xx: Add workaround for gigabit link up hardware errata. In-Reply-To: X-SA-Exim-Connect-IP: 192.168.4.242 X-SA-Exim-Mail-From: ben@decadent.org.uk X-SA-Exim-Scanned: No (on shadbolt.decadent.org.uk); SAEximRunCond expanded to false Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 3.16.61-rc1 review patch. If anyone has any objections, please let me know. ------------------ From: Yuiko Oshino commit d461e3da905332189aad546b2ad9adbe6071c7cc upstream. In certain conditions, the device may not be able to link in gigabit mode. This software workaround ensures that the device will not enter the failure state. Fixes: d0cad871703b898a442e4049c532ec39168e5b57 ("SMSC75XX USB 2.0 Gigabit Ethernet Devices") Signed-off-by: Yuiko Oshino Signed-off-by: David S. Miller Signed-off-by: Ben Hutchings --- drivers/net/usb/smsc75xx.c | 62 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) --- a/drivers/net/usb/smsc75xx.c +++ b/drivers/net/usb/smsc75xx.c @@ -81,6 +81,9 @@ static bool turbo_mode = true; module_param(turbo_mode, bool, 0644); MODULE_PARM_DESC(turbo_mode, "Enable multiple frames per Rx transaction"); +static int smsc75xx_link_ok_nopm(struct usbnet *dev); +static int smsc75xx_phy_gig_workaround(struct usbnet *dev); + static int __must_check __smsc75xx_read_reg(struct usbnet *dev, u32 index, u32 *data, int in_pm) { @@ -840,6 +843,9 @@ static int smsc75xx_phy_initialize(struc return -EIO; } + /* phy workaround for gig link */ + smsc75xx_phy_gig_workaround(dev); + smsc75xx_mdio_write(dev->net, dev->mii.phy_id, MII_ADVERTISE, ADVERTISE_ALL | ADVERTISE_CSMA | ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM); @@ -977,6 +983,62 @@ static int smsc75xx_wait_ready(struct us return -EIO; } +static int smsc75xx_phy_gig_workaround(struct usbnet *dev) +{ + struct mii_if_info *mii = &dev->mii; + int ret = 0, timeout = 0; + u32 buf, link_up = 0; + + /* Set the phy in Gig loopback */ + smsc75xx_mdio_write(dev->net, mii->phy_id, MII_BMCR, 0x4040); + + /* Wait for the link up */ + do { + link_up = smsc75xx_link_ok_nopm(dev); + usleep_range(10000, 20000); + timeout++; + } while ((!link_up) && (timeout < 1000)); + + if (timeout >= 1000) { + netdev_warn(dev->net, "Timeout waiting for PHY link up\n"); + return -EIO; + } + + /* phy reset */ + ret = smsc75xx_read_reg(dev, PMT_CTL, &buf); + if (ret < 0) { + netdev_warn(dev->net, "Failed to read PMT_CTL: %d\n", ret); + return ret; + } + + buf |= PMT_CTL_PHY_RST; + + ret = smsc75xx_write_reg(dev, PMT_CTL, buf); + if (ret < 0) { + netdev_warn(dev->net, "Failed to write PMT_CTL: %d\n", ret); + return ret; + } + + timeout = 0; + do { + usleep_range(10000, 20000); + ret = smsc75xx_read_reg(dev, PMT_CTL, &buf); + if (ret < 0) { + netdev_warn(dev->net, "Failed to read PMT_CTL: %d\n", + ret); + return ret; + } + timeout++; + } while ((buf & PMT_CTL_PHY_RST) && (timeout < 100)); + + if (timeout >= 100) { + netdev_warn(dev->net, "timeout waiting for PHY Reset\n"); + return -EIO; + } + + return 0; +} + static int smsc75xx_reset(struct usbnet *dev) { struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]);