From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 9C6F3A00C3; Thu, 20 Jan 2022 04:06:10 +0100 (CET) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 08C944121E; Thu, 20 Jan 2022 04:06:08 +0100 (CET) Received: from mga05.intel.com (mga05.intel.com [192.55.52.43]) by mails.dpdk.org (Postfix) with ESMTP id D8E384121E for ; Thu, 20 Jan 2022 04:06:05 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1642647966; x=1674183966; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=I6pZDADp5YV0mPza7V+86ZO6V//iKb3GG45B9LJUc2M=; b=aoJLvzpJNWWyp2JhtAMPCSgZh1lewsAn26ACYfl9Acn7ZZM+cQSc8q2s 6ky0ODiFzBHnp20NN/LKgcqAJp+OJOMIT1NvE4Pbf+draJqbTNKxgNE2A A2OmgmU8FZb70niUp/slyB9riTM7jKZzklEtyerBanf+os3kthIDOkUW/ xbh51sj7ai2m2qU/9SOBoQlU3Pc4+gbqWhRRPCB+qLGYcvLHvz/XPj1nH sIGt13z+7IxOuBc4D2se0JahDI6pZD0Cra98W6EDzjh5Mukd374MhCxkl dkALlLxDKbAlrPgcTPQ+MT8fVGukz8NAQ3y/0un0S7bdxpHPFI2/fxXKx w==; X-IronPort-AV: E=McAfee;i="6200,9189,10232"; a="331609490" X-IronPort-AV: E=Sophos;i="5.88,301,1635231600"; d="scan'208";a="331609490" Received: from orsmga007.jf.intel.com ([10.7.209.58]) by fmsmga105.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 19 Jan 2022 19:06:05 -0800 X-IronPort-AV: E=Sophos;i="5.88,301,1635231600"; d="scan'208";a="518444142" Received: from intel-cd-odc-steve.cd.intel.com ([10.240.178.135]) by orsmga007-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 19 Jan 2022 19:06:03 -0800 From: Steve Yang To: dev@dpdk.org Cc: Yuying.Zhang@intel.com, aman.deep.singh@intel.com, qiming.yang@intel.com, qi.z.zhang@intel.com, Steve Yang Subject: [PATCH 1/2] net/ice: add module EEPROM ops for ice Date: Thu, 20 Jan 2022 02:59:30 +0000 Message-Id: <20220120025931.574106-2-stevex.yang@intel.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20220120025931.574106-1-stevex.yang@intel.com> References: <20220120025931.574106-1-stevex.yang@intel.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Add new callbacks for eth_dev_ops of ice to get the information and data of plugin module EEPROM. Signed-off-by: Steve Yang --- drivers/net/ice/ice_ethdev.c | 160 +++++++++++++++++++++++++++++++++++ drivers/net/ice/ice_ethdev.h | 25 ++++++ 2 files changed, 185 insertions(+) diff --git a/drivers/net/ice/ice_ethdev.c b/drivers/net/ice/ice_ethdev.c index 13a7a9702a..70c162d0a8 100644 --- a/drivers/net/ice/ice_ethdev.c +++ b/drivers/net/ice/ice_ethdev.c @@ -139,6 +139,10 @@ static int ice_vlan_pvid_set(struct rte_eth_dev *dev, static int ice_get_eeprom_length(struct rte_eth_dev *dev); static int ice_get_eeprom(struct rte_eth_dev *dev, struct rte_dev_eeprom_info *eeprom); +static int ice_get_module_info(struct rte_eth_dev *dev, + struct rte_eth_dev_module_info *modinfo); +static int ice_get_module_eeprom(struct rte_eth_dev *dev, + struct rte_dev_eeprom_info *info); static int ice_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats); static int ice_stats_reset(struct rte_eth_dev *dev); @@ -238,6 +242,8 @@ static const struct eth_dev_ops ice_eth_dev_ops = { .tx_burst_mode_get = ice_tx_burst_mode_get, .get_eeprom_length = ice_get_eeprom_length, .get_eeprom = ice_get_eeprom, + .get_module_info = ice_get_module_info, + .get_module_eeprom = ice_get_module_eeprom, .stats_get = ice_stats_get, .stats_reset = ice_stats_reset, .xstats_get = ice_xstats_get, @@ -4934,6 +4940,160 @@ ice_get_eeprom(struct rte_eth_dev *dev, return 0; } +static int +ice_get_module_info(struct rte_eth_dev *dev, + struct rte_eth_dev_module_info *modinfo) +{ + struct ice_hw *hw = ICE_DEV_PRIVATE_TO_HW(dev->data->dev_private); + enum ice_status status; + u8 sff8472_comp = 0; + u8 sff8472_swap = 0; + u8 sff8636_rev = 0; + u8 value = 0; + + status = ice_aq_sff_eeprom(hw, 0, ICE_I2C_EEPROM_DEV_ADDR, 0x00, 0x00, + 0, &value, 1, 0, NULL); + if (status) + return -EIO; + + switch (value) { + case ICE_MODULE_TYPE_SFP: + status = ice_aq_sff_eeprom(hw, 0, ICE_I2C_EEPROM_DEV_ADDR, + ICE_MODULE_SFF_8472_COMP, 0x00, 0, + &sff8472_comp, 1, 0, NULL); + if (status) + return -EIO; + status = ice_aq_sff_eeprom(hw, 0, ICE_I2C_EEPROM_DEV_ADDR, + ICE_MODULE_SFF_8472_SWAP, 0x00, 0, + &sff8472_swap, 1, 0, NULL); + if (status) + return -EIO; + + if (sff8472_swap & ICE_MODULE_SFF_ADDR_MODE) { + modinfo->type = ICE_MODULE_SFF_8079; + modinfo->eeprom_len = ICE_MODULE_SFF_8079_LEN; + } else if (sff8472_comp && + (sff8472_swap & ICE_MODULE_SFF_DIAG_CAPAB)) { + modinfo->type = ICE_MODULE_SFF_8472; + modinfo->eeprom_len = ICE_MODULE_SFF_8472_LEN; + } else { + modinfo->type = ICE_MODULE_SFF_8079; + modinfo->eeprom_len = ICE_MODULE_SFF_8079_LEN; + } + break; + case ICE_MODULE_TYPE_QSFP_PLUS: + case ICE_MODULE_TYPE_QSFP28: + status = ice_aq_sff_eeprom(hw, 0, ICE_I2C_EEPROM_DEV_ADDR, + ICE_MODULE_REVISION_ADDR, 0x00, 0, + &sff8636_rev, 1, 0, NULL); + if (status) + return -EIO; + /* Check revision compliance */ + if (sff8636_rev > 0x02) { + /* Module is SFF-8636 compliant */ + modinfo->type = ICE_MODULE_SFF_8636; + modinfo->eeprom_len = ICE_MODULE_QSFP_MAX_LEN; + } else { + modinfo->type = ICE_MODULE_SFF_8436; + modinfo->eeprom_len = ICE_MODULE_QSFP_MAX_LEN; + } + break; + default: + PMD_DRV_LOG(WARNING, "SFF Module Type not recognized.\n"); + return -EINVAL; + } + return 0; +} + +static int +ice_get_module_eeprom(struct rte_eth_dev *dev, + struct rte_dev_eeprom_info *info) +{ + struct ice_hw *hw = ICE_DEV_PRIVATE_TO_HW(dev->data->dev_private); +#define SFF_READ_BLOCK_SIZE 8 +#define I2C_BUSY_TRY_TIMES 4 +#define I2C_USLEEP_MIN_TIME 1500 +#define I2C_USLEEP_MAX_TIME 2500 + uint8_t value[SFF_READ_BLOCK_SIZE] = {0}; + uint8_t addr = ICE_I2C_EEPROM_DEV_ADDR; + uint8_t *data = info->data; + enum ice_status status; + bool is_sfp = false; + uint32_t i, j; + uint32_t offset = 0; + uint8_t page = 0; + + if (!info || !info->length || !data) + return -EINVAL; + + status = ice_aq_sff_eeprom(hw, 0, addr, offset, page, 0, value, 1, 0, + NULL); + if (status) + return -EIO; + + if (value[0] == ICE_MODULE_TYPE_SFP) + is_sfp = true; + + memset(data, 0, info->length); + for (i = 0; i < info->length; i += SFF_READ_BLOCK_SIZE) { + offset = i + info->offset; + page = 0; + + /* Check if we need to access the other memory page */ + if (is_sfp) { + if (offset >= ICE_MODULE_SFF_8079_LEN) { + offset -= ICE_MODULE_SFF_8079_LEN; + addr = ICE_I2C_EEPROM_DEV_ADDR2; + } + } else { + while (offset >= ICE_MODULE_SFF_8436_LEN) { + /* Compute memory page number and offset. */ + offset -= ICE_MODULE_SFF_8436_LEN / 2; + page++; + } + } + + /* Bit 2 of eeprom address 0x02 declares upper + * pages are disabled on QSFP modules. + * SFP modules only ever use page 0. + */ + if (page == 0 || !(data[0x2] & 0x4)) { + /* If i2c bus is busy due to slow page change or + * link management access, call can fail. + * This is normal. So we retry this a few times. + */ + for (j = 0; j < I2C_BUSY_TRY_TIMES; j++) { + status = ice_aq_sff_eeprom(hw, 0, addr, offset, + page, !is_sfp, value, + SFF_READ_BLOCK_SIZE, + 0, NULL); + PMD_DRV_LOG(DEBUG, "SFF %02X %02X %02X %X = " + "%02X%02X%02X%02X." + "%02X%02X%02X%02X (%X)\n", + addr, offset, page, is_sfp, + value[0], value[1], + value[2], value[3], + value[4], value[5], + value[6], value[7], + status); + if (status) { + usleep_range(I2C_USLEEP_MIN_TIME, + I2C_USLEEP_MAX_TIME); + memset(value, 0, SFF_READ_BLOCK_SIZE); + continue; + } + break; + } + + /* Make sure we have enough room for the new block */ + if ((i + SFF_READ_BLOCK_SIZE) < info->length) + memcpy(data + i, value, SFF_READ_BLOCK_SIZE); + } + } + + return 0; +} + static void ice_stat_update_32(struct ice_hw *hw, uint32_t reg, diff --git a/drivers/net/ice/ice_ethdev.h b/drivers/net/ice/ice_ethdev.h index 1242177b42..3ed580d438 100644 --- a/drivers/net/ice/ice_ethdev.h +++ b/drivers/net/ice/ice_ethdev.h @@ -143,6 +143,31 @@ /* Max number of flexible descriptor rxdid */ #define ICE_FLEX_DESC_RXDID_MAX_NUM 64 +#define ICE_I2C_EEPROM_DEV_ADDR 0xA0 +#define ICE_I2C_EEPROM_DEV_ADDR2 0xA2 +#define ICE_MODULE_TYPE_SFP 0x03 +#define ICE_MODULE_TYPE_QSFP_PLUS 0x0D +#define ICE_MODULE_TYPE_QSFP28 0x11 +#define ICE_MODULE_SFF_ADDR_MODE 0x04 +#define ICE_MODULE_SFF_DIAG_CAPAB 0x40 +#define ICE_MODULE_REVISION_ADDR 0x01 +#define ICE_MODULE_SFF_8472_COMP 0x5E +#define ICE_MODULE_SFF_8472_SWAP 0x5C +#define ICE_MODULE_QSFP_MAX_LEN 640 + +/* EEPROM Standards for plug in modules */ +#define ICE_MODULE_SFF_8079 0x1 +#define ICE_MODULE_SFF_8079_LEN 256 +#define ICE_MODULE_SFF_8472 0x2 +#define ICE_MODULE_SFF_8472_LEN 512 +#define ICE_MODULE_SFF_8636 0x3 +#define ICE_MODULE_SFF_8636_LEN 256 +#define ICE_MODULE_SFF_8636_MAX_LEN 640 +#define ICE_MODULE_SFF_8436 0x4 +#define ICE_MODULE_SFF_8436_LEN 256 +#define ICE_MODULE_SFF_8436_MAX_LEN 640 + + /* Per-channel register definitions */ #define GLTSYN_AUX_OUT(_chan, _idx) (GLTSYN_AUX_OUT_0(_idx) + ((_chan) * 8)) #define GLTSYN_CLKO(_chan, _idx) (GLTSYN_CLKO_0(_idx) + ((_chan) * 8)) -- 2.27.0