Received: by 2002:a05:6a10:206:0:0:0:0 with SMTP id 6csp2638905pxj; Mon, 31 May 2021 07:09:00 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwDGbAUBfrNb7dUmHv+6ohUnPLMgdc32VTXrPG3UYpPbG3Sv+pS8uUCOd1QuU6f2/PuFNYR X-Received: by 2002:a5d:89c1:: with SMTP id a1mr17481374iot.73.1622470140645; Mon, 31 May 2021 07:09:00 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1622470140; cv=none; d=google.com; s=arc-20160816; b=PO0yUiVkVbB/jRQHCyRkTYAE+FIgf5RT69/BV5T78mvIsu6M2stHE0rJrKoNChpOA0 0qgJW/XvHk9CXnAjSasT0DoAe0am1EUlzEcSPdob3EZE2rBy9LfzwDYWR0rRUsWmohWZ KirtuvQP0YMPIIS0yEpBdFVSek4aFWfwHVbMgzLk2cYEMfnQC7/xR/pT8LNLSnxDRAbw jsdX3snpjI05xp/x+dN1DuztPSWcmf9EqwDi4nXYuUbSmJTBTEWdhqLBXY6loCIZwUHo /JGdTTiosRX1Mst1AD7areDWKaTREKlek/vVm9zPxO37r5JVugQUnJIftByGwg0OwJcS cY3g== 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=Ha4XUtULST0bsOyiolmtjMTX7hICJLyefIXV2hEKLAk=; b=K+CxsQ7xtxAU4KRpGnVT9wzuQ3sY3tIa8gDh8RUVwao0eQLJzH+PI+va/CWS+9v+3G As1bHukM7uHmOFd2ET1ueAZ7RvAGBmR+o4fOEsxHGGiX/MuGfnQ3Gm+Aszyj90/o1pRY bd4CYS1FxKhXwtrgcnEUz3/5fFB7S7N7OMBa3JNPZupU5Prh6li3PLXzDJMAQ/Amos4p SKzzz+4gCrOpKojgOijm6BiS3j1HT2Va/DekNVEfMIT1PM/xNqhDf15BBdUwbvqhXyx0 JTLq9UmR9OAduv/igijSMxQsVI9IY4kiGib+FhPtlnFhenfxtzDu8mycDOsRu1KRqx0V VREA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=JQkvUHEv; 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 n12si16280261jat.1.2021.05.31.07.08.47; Mon, 31 May 2021 07:09:00 -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=JQkvUHEv; 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 S231210AbhEaOJs (ORCPT + 99 others); Mon, 31 May 2021 10:09:48 -0400 Received: from mail.kernel.org ([198.145.29.99]:50374 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232563AbhEaNns (ORCPT ); Mon, 31 May 2021 09:43:48 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id D201D61480; Mon, 31 May 2021 13:29:09 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1622467750; bh=2fCkTCQwg9tlYhDVVIynxXNAjk1sn7Cgp8CtsBB+K9s=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=JQkvUHEvv5Q7rnEaQHutJuALWvPdE3+zXgA3NKHEG2rkTKfKViBfkomtEEyHn44u+ sD1N0mICPoU3OyjCRQ+xFtvc/JnS8eBWPbdp3gY+x0ZJZaA1YlUWKGuNXCcjanvf2U Li+PJzQqLJaKZUo80PDvNfFZyaxl6OsFGrEcGXMA= 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 4.14 39/79] net/mlx4: Fix EEPROM dump support Date: Mon, 31 May 2021 15:14:24 +0200 Message-Id: <20210531130637.267273312@linuxfoundation.org> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210531130636.002722319@linuxfoundation.org> References: <20210531130636.002722319@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 @@ -1983,8 +1983,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) { @@ -2019,7 +2017,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);