From patchwork Sat May 24 08:32:09 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Prashant Sreedharan X-Patchwork-Id: 352093 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 9CF1514007C for ; Sat, 24 May 2014 18:34:40 +1000 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751282AbaEXIeg (ORCPT ); Sat, 24 May 2014 04:34:36 -0400 Received: from mail-gw3-out.broadcom.com ([216.31.210.64]:61081 "EHLO mail-gw3-out.broadcom.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751207AbaEXIed (ORCPT ); Sat, 24 May 2014 04:34:33 -0400 X-IronPort-AV: E=Sophos;i="4.98,900,1392192000"; d="scan'208";a="30753259" Received: from irvexchcas08.broadcom.com (HELO IRVEXCHCAS08.corp.ad.broadcom.com) ([10.9.208.57]) by mail-gw3-out.broadcom.com with ESMTP; 24 May 2014 01:35:45 -0700 Received: from IRVEXCHSMTP1.corp.ad.broadcom.com (10.9.207.51) by IRVEXCHCAS08.corp.ad.broadcom.com (10.9.208.57) with Microsoft SMTP Server (TLS) id 14.3.174.1; Sat, 24 May 2014 01:34:32 -0700 Received: from mail-irva-13.broadcom.com (10.10.10.20) by IRVEXCHSMTP1.corp.ad.broadcom.com (10.9.207.51) with Microsoft SMTP Server id 14.3.174.1; Sat, 24 May 2014 01:34:32 -0700 Received: from prashant.broadcom.com (dhcp-10-12-137-52.irv.broadcom.com [10.12.137.52]) by mail-irva-13.broadcom.com (Postfix) with ESMTP id 3A6ED9F9F7; Sat, 24 May 2014 01:34:32 -0700 (PDT) From: Prashant Sreedharan To: CC: , Prashant Sreedharan , Michael Chan Subject: [PATCH net-next] tg3: Override clock, link aware and link idle mode during NVRAM dump Date: Sat, 24 May 2014 01:32:09 -0700 Message-ID: <1400920329-9901-1-git-send-email-prashant@broadcom.com> X-Mailer: git-send-email 1.7.1 MIME-Version: 1.0 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org When cable is not present the clock speed of some of the devices is reduced based upon power saving mode setting in NVRAM. Due to this NVRAM reads take long time to complete as a result CPU soft lockup message is seen. Fix is to override clock, disable link aware and link idle modes before NVRAM reads and restore them back after the reads are complete. During this period also check if the thread needs to be rescheduled and if there are any signals to handle. Also decrease the NVRAM command execution timeout value to 1ms. Signed-off-by: Prashant Sreedharan Signed-off-by: Michael Chan --- drivers/net/ethernet/broadcom/tg3.c | 45 +++++++++++++++++++++++++++++----- 1 files changed, 38 insertions(+), 7 deletions(-) diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c index ccd9015..3b74da5 100644 --- a/drivers/net/ethernet/broadcom/tg3.c +++ b/drivers/net/ethernet/broadcom/tg3.c @@ -3224,7 +3224,7 @@ static int tg3_nvram_read_using_eeprom(struct tg3 *tp, return 0; } -#define NVRAM_CMD_TIMEOUT 10000 +#define NVRAM_CMD_TIMEOUT 100 static int tg3_nvram_exec_cmd(struct tg3 *tp, u32 nvram_cmd) { @@ -11893,9 +11893,9 @@ static int tg3_get_eeprom_len(struct net_device *dev) static int tg3_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, u8 *data) { struct tg3 *tp = netdev_priv(dev); - int ret; + int ret, cpmu_restore = 0; u8 *pd; - u32 i, offset, len, b_offset, b_count; + u32 i, offset, len, b_offset, b_count, cpmu_val = 0; __be32 val; if (tg3_flag(tp, NO_NVRAM)) @@ -11907,6 +11907,19 @@ static int tg3_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, eeprom->magic = TG3_EEPROM_MAGIC; + /* Override clock, link aware and link idle modes */ + if (tg3_flag(tp, CPMU_PRESENT)) { + cpmu_val = tr32(TG3_CPMU_CTRL); + if (cpmu_val & (CPMU_CTRL_LINK_AWARE_MODE | + CPMU_CTRL_LINK_IDLE_MODE)) { + tw32(TG3_CPMU_CTRL, cpmu_val & + ~(CPMU_CTRL_LINK_AWARE_MODE | + CPMU_CTRL_LINK_IDLE_MODE)); + cpmu_restore = 1; + } + } + tg3_override_clk(tp); + if (offset & 3) { /* adjustments to start on required 4 byte boundary */ b_offset = offset & 3; @@ -11917,7 +11930,7 @@ static int tg3_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, } ret = tg3_nvram_read_be32(tp, offset-b_offset, &val); if (ret) - return ret; + goto eeprom_done; memcpy(data, ((char *)&val) + b_offset, b_count); len -= b_count; offset += b_count; @@ -11929,10 +11942,20 @@ static int tg3_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, for (i = 0; i < (len - (len & 3)); i += 4) { ret = tg3_nvram_read_be32(tp, offset + i, &val); if (ret) { + if (i) + i -= 4; eeprom->len += i; - return ret; + goto eeprom_done; } memcpy(pd + i, &val, 4); + if (need_resched()) { + if (signal_pending(current)) { + eeprom->len += i; + ret = -EINTR; + goto eeprom_done; + } + cond_resched(); + } } eeprom->len += i; @@ -11943,11 +11966,19 @@ static int tg3_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, b_offset = offset + len - b_count; ret = tg3_nvram_read_be32(tp, b_offset, &val); if (ret) - return ret; + goto eeprom_done; memcpy(pd, &val, b_count); eeprom->len += b_count; } - return 0; + ret = 0; + +eeprom_done: + /* Restore clock, link aware and link idle modes */ + tg3_restore_clk(tp); + if (cpmu_restore) + tw32(TG3_CPMU_CTRL, cpmu_val); + + return ret; } static int tg3_set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, u8 *data)