Received: by 2002:a05:6a10:206:0:0:0:0 with SMTP id 6csp2659103pxj; Mon, 31 May 2021 07:36:44 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzOyaeyZtyx2y1ca7rNtFymtA+ih26fR7S5IBQ+LV8T69lK6yn4LDzD/jPR/FyP3av/G7NB X-Received: by 2002:a92:2a09:: with SMTP id r9mr18086140ile.300.1622471804789; Mon, 31 May 2021 07:36:44 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1622471804; cv=none; d=google.com; s=arc-20160816; b=AXtNNTSS3k1+zLPhoHeephO4UAMbKWl3tUQRTb32JS9B9rMRHAdxtNUbIOWii/MV5R jZaT1araD4caNMLTLRdpaQ7tnyAwoJmz1fYUMjI+fHgqdAyawFj6ncm3WDtAZZe6PIUk cFm/TU0QEAgKimFi93Dp6u1mhLshxd8+8NPSDvOp0KRsgULz3NocyDnnD4NnyPhZ8WZy p9xqH4MMjV1ww7kUAS7ZJOdFCmTH/Lc2VKJ709lLEGUvsS6mPz73CeLARIleA7RFE+h3 OnqjTpfx2AW/tbg9+/H5LMvvreQPbOGxjbhei271YpeJ9g7W+yCv1fYikK+hJZ0ZqePV lW8g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=yrE/36bQjdDn8XLRdBv7Pc2v3itNgrrwwtqQZu5aTnM=; b=vYBT294t9meoY2J8T7fM7EK3FsjqVXphHUHZm4kXavlfKGgrSw0KE9LJQpg3nPzlfb 8hVBS+Jv9XdqjABNMsCDG7RCNJIUPcox2SUVMAht9HgOtlNmQeJMiiEGa9WBnCkf6fKy WyqkiiA6Ngf4sCLRkI/21IHF/jttNFhgMwtAD9FNwSn3V89DmHvPCjyjN7loFUjN4VDD OgCDE3OPwfD/L4zwQ+XbKdIlIRqMqxRNzTvd190iJBD3AXbqR5jHG8lJbDr/tKtKIWmT RgDSqN64SIYWmAR+zRgF/d7nZtc4Ru7C7Tm7jWwYsP9fiHu/DkZpucfLfJzKKcQ42FYO NXMw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=yTC5cFPI; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id w31si13907423jal.77.2021.05.31.07.36.32; Mon, 31 May 2021 07:36:44 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=yTC5cFPI; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233681AbhEaOgV (ORCPT + 99 others); Mon, 31 May 2021 10:36:21 -0400 Received: from mail.kernel.org ([198.145.29.99]:60394 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232455AbhEaNzw (ORCPT ); Mon, 31 May 2021 09:55:52 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id 35E966191F; Mon, 31 May 2021 13:34:26 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1622468067; bh=2o9jGx1w/8/zQK/iRaMTyj1xBl2wc65nIZvGqvfSc5E=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=yTC5cFPIAoamuP5nF751uPIlBtCzwO6PxDypzrZPzYspX9ASU9lAVcd9zCwH978YJ x5xRfVCvpUxAhf++uLVbGquNsEhuBUwtCCQ2DzSlXMUtv4GS/e46MJj9rXGgn1IZEH iwjpO3DCdoxSRhgEkFUmLxc5bHgpx5kzvOjgQ2ig= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Vladyslav Tarasiuk , Tariq Toukan , "David S. Miller" Subject: [PATCH 5.10 104/252] net/mlx4: Fix EEPROM dump support Date: Mon, 31 May 2021 15:12:49 +0200 Message-Id: <20210531130701.530255707@linuxfoundation.org> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210531130657.971257589@linuxfoundation.org> References: <20210531130657.971257589@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Vladyslav Tarasiuk commit db825feefc6868896fed5e361787ba3bee2fd906 upstream. Fix SFP and QSFP* EEPROM queries by setting i2c_address, offset and page number correctly. For SFP set the following params: - I2C address for offsets 0-255 is 0x50. For 256-511 - 0x51. - Page number is zero. - Offset is 0-255. At the same time, QSFP* parameters are different: - I2C address is always 0x50. - Page number is not limited to zero. - Offset is 0-255 for page zero and 128-255 for others. To set parameters accordingly to cable used, implement function to query module ID and implement respective helper functions to set parameters correctly. Fixes: 135dd9594f12 ("net/mlx4_en: ethtool, Remove unsupported SFP EEPROM high pages query") Signed-off-by: Vladyslav Tarasiuk Signed-off-by: Tariq Toukan Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/mellanox/mlx4/en_ethtool.c | 4 drivers/net/ethernet/mellanox/mlx4/port.c | 107 +++++++++++++++++++++++- 2 files changed, 104 insertions(+), 7 deletions(-) --- a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c @@ -2027,8 +2027,6 @@ static int mlx4_en_set_tunable(struct ne return ret; } -#define MLX4_EEPROM_PAGE_LEN 256 - static int mlx4_en_get_module_info(struct net_device *dev, struct ethtool_modinfo *modinfo) { @@ -2063,7 +2061,7 @@ static int mlx4_en_get_module_info(struc break; case MLX4_MODULE_ID_SFP: modinfo->type = ETH_MODULE_SFF_8472; - modinfo->eeprom_len = MLX4_EEPROM_PAGE_LEN; + modinfo->eeprom_len = ETH_MODULE_SFF_8472_LEN; break; default: return -EINVAL; --- a/drivers/net/ethernet/mellanox/mlx4/port.c +++ b/drivers/net/ethernet/mellanox/mlx4/port.c @@ -1973,6 +1973,7 @@ EXPORT_SYMBOL(mlx4_get_roce_gid_from_sla #define I2C_ADDR_LOW 0x50 #define I2C_ADDR_HIGH 0x51 #define I2C_PAGE_SIZE 256 +#define I2C_HIGH_PAGE_SIZE 128 /* Module Info Data */ struct mlx4_cable_info { @@ -2026,6 +2027,88 @@ static inline const char *cable_info_mad return "Unknown Error"; } +static int mlx4_get_module_id(struct mlx4_dev *dev, u8 port, u8 *module_id) +{ + struct mlx4_cmd_mailbox *inbox, *outbox; + struct mlx4_mad_ifc *inmad, *outmad; + struct mlx4_cable_info *cable_info; + int ret; + + inbox = mlx4_alloc_cmd_mailbox(dev); + if (IS_ERR(inbox)) + return PTR_ERR(inbox); + + outbox = mlx4_alloc_cmd_mailbox(dev); + if (IS_ERR(outbox)) { + mlx4_free_cmd_mailbox(dev, inbox); + return PTR_ERR(outbox); + } + + inmad = (struct mlx4_mad_ifc *)(inbox->buf); + outmad = (struct mlx4_mad_ifc *)(outbox->buf); + + inmad->method = 0x1; /* Get */ + inmad->class_version = 0x1; + inmad->mgmt_class = 0x1; + inmad->base_version = 0x1; + inmad->attr_id = cpu_to_be16(0xFF60); /* Module Info */ + + cable_info = (struct mlx4_cable_info *)inmad->data; + cable_info->dev_mem_address = 0; + cable_info->page_num = 0; + cable_info->i2c_addr = I2C_ADDR_LOW; + cable_info->size = cpu_to_be16(1); + + ret = mlx4_cmd_box(dev, inbox->dma, outbox->dma, port, 3, + MLX4_CMD_MAD_IFC, MLX4_CMD_TIME_CLASS_C, + MLX4_CMD_NATIVE); + if (ret) + goto out; + + if (be16_to_cpu(outmad->status)) { + /* Mad returned with bad status */ + ret = be16_to_cpu(outmad->status); + mlx4_warn(dev, + "MLX4_CMD_MAD_IFC Get Module ID attr(%x) port(%d) i2c_addr(%x) offset(%d) size(%d): Response Mad Status(%x) - %s\n", + 0xFF60, port, I2C_ADDR_LOW, 0, 1, ret, + cable_info_mad_err_str(ret)); + ret = -ret; + goto out; + } + cable_info = (struct mlx4_cable_info *)outmad->data; + *module_id = cable_info->data[0]; +out: + mlx4_free_cmd_mailbox(dev, inbox); + mlx4_free_cmd_mailbox(dev, outbox); + return ret; +} + +static void mlx4_sfp_eeprom_params_set(u8 *i2c_addr, u8 *page_num, u16 *offset) +{ + *i2c_addr = I2C_ADDR_LOW; + *page_num = 0; + + if (*offset < I2C_PAGE_SIZE) + return; + + *i2c_addr = I2C_ADDR_HIGH; + *offset -= I2C_PAGE_SIZE; +} + +static void mlx4_qsfp_eeprom_params_set(u8 *i2c_addr, u8 *page_num, u16 *offset) +{ + /* Offsets 0-255 belong to page 0. + * Offsets 256-639 belong to pages 01, 02, 03. + * For example, offset 400 is page 02: 1 + (400 - 256) / 128 = 2 + */ + if (*offset < I2C_PAGE_SIZE) + *page_num = 0; + else + *page_num = 1 + (*offset - I2C_PAGE_SIZE) / I2C_HIGH_PAGE_SIZE; + *i2c_addr = I2C_ADDR_LOW; + *offset -= *page_num * I2C_HIGH_PAGE_SIZE; +} + /** * mlx4_get_module_info - Read cable module eeprom data * @dev: mlx4_dev. @@ -2045,12 +2128,30 @@ int mlx4_get_module_info(struct mlx4_dev struct mlx4_cmd_mailbox *inbox, *outbox; struct mlx4_mad_ifc *inmad, *outmad; struct mlx4_cable_info *cable_info; - u16 i2c_addr; + u8 module_id, i2c_addr, page_num; int ret; if (size > MODULE_INFO_MAX_READ) size = MODULE_INFO_MAX_READ; + ret = mlx4_get_module_id(dev, port, &module_id); + if (ret) + return ret; + + switch (module_id) { + case MLX4_MODULE_ID_SFP: + mlx4_sfp_eeprom_params_set(&i2c_addr, &page_num, &offset); + break; + case MLX4_MODULE_ID_QSFP: + case MLX4_MODULE_ID_QSFP_PLUS: + case MLX4_MODULE_ID_QSFP28: + mlx4_qsfp_eeprom_params_set(&i2c_addr, &page_num, &offset); + break; + default: + mlx4_err(dev, "Module ID not recognized: %#x\n", module_id); + return -EINVAL; + } + inbox = mlx4_alloc_cmd_mailbox(dev); if (IS_ERR(inbox)) return PTR_ERR(inbox); @@ -2076,11 +2177,9 @@ int mlx4_get_module_info(struct mlx4_dev */ size -= offset + size - I2C_PAGE_SIZE; - i2c_addr = I2C_ADDR_LOW; - cable_info = (struct mlx4_cable_info *)inmad->data; cable_info->dev_mem_address = cpu_to_be16(offset); - cable_info->page_num = 0; + cable_info->page_num = page_num; cable_info->i2c_addr = i2c_addr; cable_info->size = cpu_to_be16(size);