From patchwork Mon Apr 22 13:48:09 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Kravkov X-Patchwork-Id: 238537 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 F1BCC2C014A for ; Mon, 22 Apr 2013 23:48:38 +1000 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754119Ab3DVNsf (ORCPT ); Mon, 22 Apr 2013 09:48:35 -0400 Received: from mms2.broadcom.com ([216.31.210.18]:3995 "EHLO mms2.broadcom.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751771Ab3DVNsc (ORCPT ); Mon, 22 Apr 2013 09:48:32 -0400 Received: from [10.9.208.57] by mms2.broadcom.com with ESMTP (Broadcom SMTP Relay (Email Firewall v6.5)); Mon, 22 Apr 2013 06:43:05 -0700 X-Server-Uuid: 4500596E-606A-40F9-852D-14843D8201B2 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.1.438.0; Mon, 22 Apr 2013 06:48:22 -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.1.438.0; Mon, 22 Apr 2013 06:48:22 -0700 Received: from lb-tlvb-dmitry.il.broadcom.com ( lb-tlvb-dmitry.il.broadcom.com [10.185.7.55]) by mail-irva-13.broadcom.com (Postfix) with ESMTP id 076293928A; Mon, 22 Apr 2013 06:48:20 -0700 (PDT) From: "Dmitry Kravkov" To: davem@davemloft.net, netdev@vger.kernel.org, eilong@broadcom.com cc: romieu@fz.zoreil.com, "Dmitry Kravkov" Subject: [PATCH v4 net-next 4/6] bnx2x: add additional regions for CRC memory test Date: Mon, 22 Apr 2013 16:48:09 +0300 Message-ID: <1366638491-27184-5-git-send-email-dmitry@broadcom.com> X-Mailer: git-send-email 1.8.1.4 In-Reply-To: <1366638491-27184-1-git-send-email-dmitry@broadcom.com> References: <1366638491-27184-1-git-send-email-dmitry@broadcom.com> MIME-Version: 1.0 X-WSS-ID: 7D6BE1E31R01201191-01-01 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org a. Common tree of `dir` structures. b. Multi-port devices structures. CC: Francious Romieu Signed-off-by: Dmitry Kravkov Signed-off-by: Eilon Greenstein --- drivers/net/ethernet/broadcom/bnx2x/bnx2x.h | 7 +- .../net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c | 201 +++++++++++++++++++-- 2 files changed, 185 insertions(+), 23 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h index c630342..87629fd 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h @@ -850,6 +850,9 @@ struct bnx2x_common { #define CHIP_IS_57840_VF(bp) (CHIP_NUM(bp) == CHIP_NUM_57840_VF) #define CHIP_IS_E1H(bp) (CHIP_IS_57711(bp) || \ CHIP_IS_57711E(bp)) +#define CHIP_IS_57811xx(bp) (CHIP_IS_57811(bp) || \ + CHIP_IS_57811_MF(bp) || \ + CHIP_IS_57811_VF(bp)) #define CHIP_IS_E2(bp) (CHIP_IS_57712(bp) || \ CHIP_IS_57712_MF(bp) || \ CHIP_IS_57712_VF(bp)) @@ -859,9 +862,7 @@ struct bnx2x_common { CHIP_IS_57810(bp) || \ CHIP_IS_57810_MF(bp) || \ CHIP_IS_57810_VF(bp) || \ - CHIP_IS_57811(bp) || \ - CHIP_IS_57811_MF(bp) || \ - CHIP_IS_57811_VF(bp) || \ + CHIP_IS_57811xx(bp) || \ CHIP_IS_57840(bp) || \ CHIP_IS_57840_MF(bp) || \ CHIP_IS_57840_VF(bp)) diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c index 8d5c21e..f07021b 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c @@ -2595,14 +2595,168 @@ static int bnx2x_test_ext_loopback(struct bnx2x *bp) return rc; } +struct code_entry { + u32 sram_start_addr; + u32 code_attribute; +#define CODE_IMAGE_TYPE_MASK 0xf0800003 +#define CODE_IMAGE_VNTAG_PROFILES_DATA 0xd0000003 +#define CODE_IMAGE_LENGTH_MASK 0x007ffffc +#define CODE_IMAGE_TYPE_EXTENDED_DIR 0xe0000000 + u32 nvm_start_addr; +}; + +#define CODE_ENTRY_MAX 16 +#define CODE_ENTRY_EXTENDED_DIR_IDX 15 +#define MAX_IMAGES_IN_EXTENDED_DIR 64 +#define NVRAM_DIR_OFFSET 0x14 + +#define EXTENDED_DIR_EXISTS(code) \ + ((code & CODE_IMAGE_TYPE_MASK) == CODE_IMAGE_TYPE_EXTENDED_DIR && \ + (code & CODE_IMAGE_LENGTH_MASK) != 0) + #define CRC32_RESIDUAL 0xdebb20e3 +#define CRC_BUFF_SIZE 256 + +static int bnx2x_nvram_crc(struct bnx2x *bp, + int offset, + int size, + u8 *buff) +{ + u32 crc = ~0; + int rc = 0, done = 0; + + DP(BNX2X_MSG_ETHTOOL | BNX2X_MSG_NVM, + "NVRAM CRC from 0x%08x to 0x%08x\n", offset, offset + size); + + while (done < size) { + int count = min_t(int, size - done, CRC_BUFF_SIZE); + + rc = bnx2x_nvram_read(bp, offset + done, buff, count); + + if (rc) + return rc; + + crc = crc32_le(crc, buff, count); + done += count; + } + + if (crc != CRC32_RESIDUAL) + rc = -EINVAL; + + return rc; +} + +static int bnx2x_test_nvram_dir(struct bnx2x *bp, + struct code_entry *entry, + u8 *buff) +{ + size_t size = entry->code_attribute & CODE_IMAGE_LENGTH_MASK; + u32 type = entry->code_attribute & CODE_IMAGE_TYPE_MASK; + int rc; + + /* Zero-length images and AFEX profiles do not have CRC */ + if (size == 0 || type == CODE_IMAGE_VNTAG_PROFILES_DATA) + return 0; + + rc = bnx2x_nvram_crc(bp, entry->nvm_start_addr, size, buff); + if (rc) + DP(BNX2X_MSG_ETHTOOL | BNX2X_MSG_NVM, + "image %x has failed crc test (rc %d)\n", type, rc); + + return rc; +} + +static int bnx2x_test_dir_entry(struct bnx2x *bp, u32 addr, u8 *buff) +{ + int rc; + struct code_entry entry; + + rc = bnx2x_nvram_read32(bp, addr, (u32 *)&entry, sizeof(entry)); + if (rc) + return rc; + + return bnx2x_test_nvram_dir(bp, &entry, buff); +} + +static int bnx2x_test_nvram_ext_dirs(struct bnx2x *bp, u8 *buff) +{ + u32 rc, cnt, dir_offset = NVRAM_DIR_OFFSET; + struct code_entry entry; + int i; + + rc = bnx2x_nvram_read32(bp, + dir_offset + + sizeof(entry) * CODE_ENTRY_EXTENDED_DIR_IDX, + (u32 *)&entry, sizeof(entry)); + if (rc) + return rc; + + if (!EXTENDED_DIR_EXISTS(entry.code_attribute)) + return 0; + + rc = bnx2x_nvram_read32(bp, entry.nvm_start_addr, + &cnt, sizeof(u32)); + if (rc) + return rc; + + dir_offset = entry.nvm_start_addr + 8; + + for (i = 0; i < cnt && i < MAX_IMAGES_IN_EXTENDED_DIR; i++) { + rc = bnx2x_test_dir_entry(bp, dir_offset + + sizeof(struct code_entry) * i, + buff); + if (rc) + return rc; + } + + return 0; +} + +static int bnx2x_test_nvram_dirs(struct bnx2x *bp, u8 *buff) +{ + u32 rc, dir_offset = NVRAM_DIR_OFFSET; + int i; + + DP(BNX2X_MSG_ETHTOOL | BNX2X_MSG_NVM, "NVRAM DIRS CRC test-set\n"); + + for (i = 0; i < CODE_ENTRY_EXTENDED_DIR_IDX; i++) { + rc = bnx2x_test_dir_entry(bp, dir_offset + + sizeof(struct code_entry) * i, + buff); + if (rc) + return rc; + } + + return bnx2x_test_nvram_ext_dirs(bp, buff); +} + +struct crc_pair { + int offset; + int size; +}; + +static int bnx2x_test_nvram_tbl(struct bnx2x *bp, + const struct crc_pair *nvram_tbl, u8 *buf) +{ + int i; + + for (i = 0; nvram_tbl[i].size; i++) { + int rc = bnx2x_nvram_crc(bp, nvram_tbl[i].offset, + nvram_tbl[i].size, buf); + if (rc) { + DP(BNX2X_MSG_ETHTOOL | BNX2X_MSG_NVM, + "nvram_tbl[%d] has failed crc test (rc %d)\n", + i, rc); + return rc; + } + } + + return 0; +} static int bnx2x_test_nvram(struct bnx2x *bp) { - static const struct { - int offset; - int size; - } nvram_tbl[] = { + const struct crc_pair nvram_tbl[] = { { 0, 0x14 }, /* bootstrap */ { 0x14, 0xec }, /* dir */ { 0x100, 0x350 }, /* manuf_info */ @@ -2611,14 +2765,20 @@ static int bnx2x_test_nvram(struct bnx2x *bp) { 0x708, 0x70 }, /* manuf_key_info */ { 0, 0 } }; + const struct crc_pair nvram_tbl2[] = { + { 0x7e8, 0x350 }, /* manuf_info2 */ + { 0xb38, 0xf0 }, /* feature_info */ + { 0, 0 } + }; + u8 *buf; - int i, rc; - u32 magic, crc; + int rc; + u32 magic; if (BP_NOMCP(bp)) return 0; - buf = kmalloc(0x350, GFP_KERNEL); + buf = kmalloc(CRC_BUFF_SIZE, GFP_KERNEL); if (!buf) { DP(BNX2X_MSG_ETHTOOL | BNX2X_MSG_NVM, "kmalloc failed\n"); rc = -ENOMEM; @@ -2639,25 +2799,26 @@ static int bnx2x_test_nvram(struct bnx2x *bp) goto test_nvram_exit; } - for (i = 0; nvram_tbl[i].size; i++) { + DP(BNX2X_MSG_ETHTOOL | BNX2X_MSG_NVM, "Port 0 CRC test-set\n"); + rc = bnx2x_test_nvram_tbl(bp, nvram_tbl, buf); + if (rc) + goto test_nvram_exit; - rc = bnx2x_nvram_read(bp, nvram_tbl[i].offset, buf, - nvram_tbl[i].size); - if (rc) { - DP(BNX2X_MSG_ETHTOOL | BNX2X_MSG_NVM, - "nvram_tbl[%d] read data (rc %d)\n", i, rc); - goto test_nvram_exit; - } + if (!CHIP_IS_E1x(bp) && !CHIP_IS_57811xx(bp)) { + u32 hide = SHMEM_RD(bp, dev_info.shared_hw_config.config2) & + SHARED_HW_CFG_HIDE_PORT1; - crc = ether_crc_le(nvram_tbl[i].size, buf); - if (crc != CRC32_RESIDUAL) { + if (!hide) { DP(BNX2X_MSG_ETHTOOL | BNX2X_MSG_NVM, - "nvram_tbl[%d] wrong crc value (0x%08x)\n", i, crc); - rc = -ENODEV; - goto test_nvram_exit; + "Port 1 CRC test-set\n"); + rc = bnx2x_test_nvram_tbl(bp, nvram_tbl2, buf); + if (rc) + goto test_nvram_exit; } } + rc = bnx2x_test_nvram_dirs(bp, buf); + test_nvram_exit: kfree(buf); return rc;