From patchwork Mon Jan 2 17:08:51 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Javier Martinez Canillas X-Patchwork-Id: 133875 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 88F131007D2 for ; Tue, 3 Jan 2012 04:08:18 +1100 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753236Ab2ABRIN (ORCPT ); Mon, 2 Jan 2012 12:08:13 -0500 Received: from mail-wi0-f174.google.com ([209.85.212.174]:46990 "EHLO mail-wi0-f174.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753037Ab2ABRII (ORCPT ); Mon, 2 Jan 2012 12:08:08 -0500 Received: by wibhm6 with SMTP id hm6so8519588wib.19 for ; Mon, 02 Jan 2012 09:08:07 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references; bh=I9sLFvSijRD7vrbaOqqKM1HBTG13UUfzHDSCJOXCejk=; b=Fc9qlbeXOBBrl8BSG4o6RMg3YIeJ+tTEvWAZdg9GO2uL5xHv/59s9sNYO+mXvVLTgw 3VD4giuXzAd3YjkpRshIOst5DFxJpR88g7XHaL4sSRLJn13EksnhypniZb0lxUQS7Tmg UrDmoMbgMx6KrvxDx4MPGxF7QOioCV5ngB55A= Received: by 10.181.13.179 with SMTP id ez19mr107279365wid.11.1325524087701; Mon, 02 Jan 2012 09:08:07 -0800 (PST) Received: from localhost.localdomain (249.Red-80-33-164.staticIP.rima-tde.net. [80.33.164.249]) by mx.google.com with ESMTPS id fy5sm119510947wib.7.2012.01.02.09.08.06 (version=TLSv1/SSLv3 cipher=OTHER); Mon, 02 Jan 2012 09:08:06 -0800 (PST) From: Javier Martinez Canillas To: Steve Glendinning Cc: Ben Hutchings , Enric Balletbo i Serra , netdev@vger.kernel.org, Javier Martinez Canillas Subject: [PATCH 2/2] net/smsc911x: Check if PHY is in operational mode before software reset Date: Mon, 2 Jan 2012 18:08:51 +0100 Message-Id: <1325524131-14585-2-git-send-email-martinez.javier@gmail.com> X-Mailer: git-send-email 1.7.4.1 In-Reply-To: <1325524131-14585-1-git-send-email-martinez.javier@gmail.com> References: <1325524131-14585-1-git-send-email-martinez.javier@gmail.com> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org SMSC LAN generation 4 chips integrate an IEEE 802.3 ethernet physical layer. The PHY driver for this integrated chip enable an energy detect power-down mode. When the PHY is in a power-down mode, it prevents the MAC portion chip to be software reseted. That means that if we compile the kernel with the configuration option SMSC_PHY enabled and try to bring the network interface up without an cable plug-ed the PHY will be in a low power mode and the software reset will fail returning -EIO to user-space: root@igep00x0:~# ifconfig eth0 up ifconfig: SIOCSIFFLAGS: Input/output error This patch disable the energy detect power-down mode before trying to software reset the LAN chip and re-enables after it was reseted successfully. Signed-off-by: Javier Martinez Canillas --- drivers/net/ethernet/smsc/smsc911x.c | 88 ++++++++++++++++++++++++++++++++++ 1 files changed, 88 insertions(+), 0 deletions(-) diff --git a/drivers/net/ethernet/smsc/smsc911x.c b/drivers/net/ethernet/smsc/smsc911x.c index 8843071..2a63e11 100644 --- a/drivers/net/ethernet/smsc/smsc911x.c +++ b/drivers/net/ethernet/smsc/smsc911x.c @@ -1243,10 +1243,88 @@ static void smsc911x_rx_multicast_update_workaround(struct smsc911x_data *pdata) spin_unlock(&pdata->mac_lock); } +static int smsc911x_phy_disable_energy_detect(struct smsc911x_data *pdata) +{ + int rc = 0; + + if (!pdata->phy_dev) + return rc; + + rc = phy_read(pdata->phy_dev, MII_LAN83C185_CTRL_STATUS); + + if (rc < 0) { + SMSC_WARN(pdata, drv, "Failed reading PHY control reg"); + return rc; + } + + /* If energy is detected the PHY is already awake so is not necessary + * to disable the energy detect power-down mode. */ + if ((rc & MII_LAN83C185_EDPWRDOWN) && + !(rc & MII_LAN83C185_ENERGYON)) { + /* Disable energy detect mode for this SMSC Transceivers */ + rc = phy_write(pdata->phy_dev, MII_LAN83C185_CTRL_STATUS, + rc & (~MII_LAN83C185_EDPWRDOWN)); + + if (rc < 0) { + SMSC_WARN(pdata, drv, "Failed writing PHY control reg"); + return rc; + } + + mdelay(1); + } + + return 0; +} + +static int smsc911x_phy_enable_energy_detect(struct smsc911x_data *pdata) +{ + int rc = 0; + + if (!pdata->phy_dev) + return rc; + + rc = phy_read(pdata->phy_dev, MII_LAN83C185_CTRL_STATUS); + + if (rc < 0) { + SMSC_WARN(pdata, drv, "Failed reading PHY control reg"); + return rc; + } + + /* Only enable if energy detect mode is already disabled */ + if (!(rc & MII_LAN83C185_EDPWRDOWN)) { + mdelay(100); + /* Enable energy detect mode for this SMSC Transceivers */ + rc = phy_write(pdata->phy_dev, MII_LAN83C185_CTRL_STATUS, + rc | MII_LAN83C185_EDPWRDOWN); + + if (rc < 0) { + SMSC_WARN(pdata, drv, "Failed writing PHY control reg"); + return rc; + } + + mdelay(1); + } + return 0; +} + static int smsc911x_soft_reset(struct smsc911x_data *pdata) { unsigned int timeout; unsigned int temp; + int ret; + + /* LAN9210/LAN9211/LAN9220/LAN9221 chips have an internal PHY that + * are initialized in a Energy Detect Power-Down mode that prevents + * the MAC chip to be software reseted. So we have to wakeup the PHY + * before */ + if (pdata->generation == 4) { + ret = smsc911x_phy_disable_energy_detect(pdata); + + if (ret) { + SMSC_WARN(pdata, drv, "Failed to wakeup the PHY chip"); + return ret; + } + } /* Reset the LAN911x */ smsc911x_reg_write(pdata, HW_CFG, HW_CFG_SRST_); @@ -1260,6 +1338,16 @@ static int smsc911x_soft_reset(struct smsc911x_data *pdata) SMSC_WARN(pdata, drv, "Failed to complete reset"); return -EIO; } + + if (pdata->generation == 4) { + ret = smsc911x_phy_enable_energy_detect(pdata); + + if (ret) { + SMSC_WARN(pdata, drv, "Failed to wakeup the PHY chip"); + return ret; + } + } + return 0; }