From patchwork Tue Sep 11 10:12:23 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marek Vasut X-Patchwork-Id: 10595411 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 91F7A1575 for ; Tue, 11 Sep 2018 10:12:33 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 80EF129199 for ; Tue, 11 Sep 2018 10:12:33 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 7457C291B2; Tue, 11 Sep 2018 10:12:33 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B8B6029199 for ; Tue, 11 Sep 2018 10:12:32 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727669AbeIKPLH (ORCPT ); Tue, 11 Sep 2018 11:11:07 -0400 Received: from mail-out.m-online.net ([212.18.0.10]:38410 "EHLO mail-out.m-online.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726885AbeIKPLH (ORCPT ); Tue, 11 Sep 2018 11:11:07 -0400 Received: from frontend01.mail.m-online.net (unknown [192.168.8.182]) by mail-out.m-online.net (Postfix) with ESMTP id 428ghC5ppgz1qxCr; Tue, 11 Sep 2018 12:12:27 +0200 (CEST) Received: from localhost (dynscan1.mnet-online.de [192.168.6.70]) by mail.m-online.net (Postfix) with ESMTP id 428ghC0FGtz1qr2s; Tue, 11 Sep 2018 12:12:27 +0200 (CEST) X-Virus-Scanned: amavisd-new at mnet-online.de Received: from mail.mnet-online.de ([192.168.8.182]) by localhost (dynscan1.mail.m-online.net [192.168.6.70]) (amavisd-new, port 10024) with ESMTP id OBJBNsrFZVTH; Tue, 11 Sep 2018 12:12:26 +0200 (CEST) X-Auth-Info: ywozfKxtRV9RHWYoXEzL+wi8nnqoujIdHlBEEk2HnoQ= Received: from kurokawa.lan (ip-86-49-107-50.net.upcbroadband.cz [86.49.107.50]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.mnet-online.de (Postfix) with ESMTPSA; Tue, 11 Sep 2018 12:12:26 +0200 (CEST) From: Marek Vasut To: linux-usb@vger.kernel.org Cc: Marek Vasut , "David S . Miller" , Nisar Sayed , Woojung Huh Subject: [PATCH] smsc95xx: Add support for automated PHY address detection Date: Tue, 11 Sep 2018 12:12:23 +0200 Message-Id: <20180911101223.4217-1-marex@denx.de> X-Mailer: git-send-email 2.18.0 Sender: linux-usb-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP The SMSC95xx chip can use either the internal PHY or an external one. Currently, the driver hard-codes support for the internal PHY only. This patch reads out the HW_CFG register to determine whether external PHY is attached or not. If an external PHY is not attached, the driver falls back to internal PHY with fixed PHY address 0x1. If an external PHY is attached, the driver scans the entire address range of the MDIO bus to determine whether there is a valid external PHY attached. The scanning happens from the end of the address range, since some PHYs also respond to address 0, which is considered a MDIO broadcast address by them. We want to obtain their real MDIO address instead. Signed-off-by: Marek Vasut Cc: David S. Miller Cc: Nisar Sayed Cc: Woojung Huh --- drivers/net/usb/smsc95xx.c | 42 +++++++++++++++++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c index 06b4d290784d..014bb71ce8a8 100644 --- a/drivers/net/usb/smsc95xx.c +++ b/drivers/net/usb/smsc95xx.c @@ -983,6 +983,40 @@ static int smsc95xx_start_rx_path(struct usbnet *dev, int in_pm) return __smsc95xx_write_reg(dev, MAC_CR, pdata->mac_cr, in_pm); } +static int smsc95xx_phy_address(struct usbnet *dev) +{ + u32 read_buf; + int ret, id1, id2, phyad; + + ret = smsc95xx_read_reg(dev, HW_CFG, &read_buf); + if (ret < 0) + return ret; + + /* Check if using external PHY, if not, use internal PHY address */ + if (!(read_buf & HW_CFG_PSEL_)) + return SMSC95XX_INTERNAL_PHY_ID; + + /* + * Detect external PHY address. Here we probe the MDIO bus from + * the highest address, since some PHYs respond also on address + * zero, which they consider MDIO broadcast address. We really + * want to get their proper address instead though, so we scan + * address zero last. + */ + for (phyad = 0x1f; phyad >= 0; phyad--) { + id1 = smsc95xx_mdio_read(dev->net, phyad, MII_PHYSID1); + id2 = smsc95xx_mdio_read(dev->net, phyad, MII_PHYSID2); + /* Check for valid response from the PHY */ + if (id1 > 0 && id2 > 0 && id1 != 0x7fff && id2 != 0xffff) + return phyad; + } + + /* No PHY found. */ + netdev_warn(dev->net, "cannot detect any PHY"); + + return -ENODEV; +} + static int smsc95xx_phy_initialize(struct usbnet *dev) { int bmcr, ret, timeout = 0; @@ -993,7 +1027,13 @@ static int smsc95xx_phy_initialize(struct usbnet *dev) dev->mii.mdio_write = smsc95xx_mdio_write; dev->mii.phy_id_mask = 0x1f; dev->mii.reg_num_mask = 0x1f; - dev->mii.phy_id = SMSC95XX_INTERNAL_PHY_ID; + + /* Determine PHY address */ + ret = smsc95xx_phy_address(dev); + if (ret) + return ret; + + dev->mii.phy_id = ret; /* reset phy and wait for reset to complete */ smsc95xx_mdio_write(dev->net, dev->mii.phy_id, MII_BMCR, BMCR_RESET);