From patchwork Wed Dec 20 08:47:06 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Qiming Yang X-Patchwork-Id: 135381 X-Patchwork-Delegate: qi.z.zhang@intel.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 1F17B43732; Wed, 20 Dec 2023 10:08:48 +0100 (CET) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id CE0C640689; Wed, 20 Dec 2023 10:08:47 +0100 (CET) Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.9]) by mails.dpdk.org (Postfix) with ESMTP id CE55B40266 for ; Wed, 20 Dec 2023 10:08:45 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1703063326; x=1734599326; h=from:to:cc:subject:date:message-id:mime-version: content-transfer-encoding; bh=EmykrivKo51qes8vowAP3em4YwZNfZo6JsrW/k6hvi0=; b=ZGOQmBa7sN16vbxc3eXQ9oDOjRNnvVU8xM8/Qe/Ir0tHBUkSv/yk4/5G d+J4ht7WL2o1Y8O1LtNYYl/tgcRb0kVgdduob16utxkbCgVm1BJg/TS2S bhZuJ9rX/WwonQKZek/9tKJXYHB0DQcEHkrtSYUXAfficcT9AXGp+XNTO 5T/RQ8+8/isdAVsdbJWGk5NzQgkOIbG9detlGmuukSWQQCN+0qsTd0Zf5 aRjxLyaoACBCOcDH4ls8Jw94/hN6wyl5sEXf5GOBmOEj/1kmYaATtTzTa Ixs8SBDarnNn8Rw/gJzZ6jY1DDhEqjZ3U6SiFLUNAQhi70vaLgkDk7KGs Q==; X-IronPort-AV: E=McAfee;i="6600,9927,10929"; a="2640842" X-IronPort-AV: E=Sophos;i="6.04,291,1695711600"; d="scan'208";a="2640842" Received: from orsmga004.jf.intel.com ([10.7.209.38]) by fmvoesa103.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 20 Dec 2023 01:08:36 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10929"; a="899658083" X-IronPort-AV: E=Sophos;i="6.04,290,1695711600"; d="scan'208";a="899658083" Received: from dpdk-qiming3.sh.intel.com ([10.67.110.238]) by orsmga004.jf.intel.com with ESMTP; 20 Dec 2023 01:08:34 -0800 From: Qiming Yang To: dev@dpdk.org Cc: qi.z.zhang@intel.com, Qiming Yang Subject: [PATCH] net/i40e: support FEC feature Date: Wed, 20 Dec 2023 08:47:06 +0000 Message-Id: <20231220084706.446508-1-qiming.yang@intel.com> X-Mailer: git-send-email 2.25.1 MIME-Version: 1.0 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 This patch enabled FEC set and get functions. Signed-off-by: Qiming Yang --- drivers/net/i40e/i40e_ethdev.c | 183 +++++++++++++++++++++++++++++++++ 1 file changed, 183 insertions(+) diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c index 3ca226156b..1eb49176d1 100644 --- a/drivers/net/i40e/i40e_ethdev.c +++ b/drivers/net/i40e/i40e_ethdev.c @@ -405,6 +405,11 @@ static void i40e_ethertype_filter_restore(struct i40e_pf *pf); static void i40e_tunnel_filter_restore(struct i40e_pf *pf); static void i40e_filter_restore(struct i40e_pf *pf); static void i40e_notify_all_vfs_link_status(struct rte_eth_dev *dev); +static int i40e_fec_get_capability(struct rte_eth_dev *dev, struct rte_eth_fec_capa *speed_fec_capa, + unsigned int num); +static int i40e_fec_get(struct rte_eth_dev *dev, uint32_t *fec_capa); +static int i40e_fec_set(struct rte_eth_dev *dev, uint32_t fec_capa); + static const char *const valid_keys[] = { ETH_I40E_FLOATING_VEB_ARG, @@ -519,6 +524,9 @@ static const struct eth_dev_ops i40e_eth_dev_ops = { .tm_ops_get = i40e_tm_ops_get, .tx_done_cleanup = i40e_tx_done_cleanup, .get_monitor_addr = i40e_get_monitor_addr, + .fec_get_capability = i40e_fec_get_capability, + .fec_get = i40e_fec_get, + .fec_set = i40e_fec_set, }; /* store statistics names and its offset in stats structure */ @@ -12159,6 +12167,181 @@ i40e_cloud_filter_qinq_create(struct i40e_pf *pf) return ret; } +static int +i40e_fec_get_capability(struct rte_eth_dev *dev, struct rte_eth_fec_capa *speed_fec_capa, + unsigned int num) +{ + struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private); + num = 0; + + if (hw->mac.type == I40E_MAC_X722 && + !(hw->flags & I40E_HW_FLAG_X722_FEC_REQUEST_CAPABLE)) { + PMD_DRV_LOG(ERR, "Setting FEC encoding not supported by" + " firmware. Please update the NVM image.\n"); + return 0; + } + + if (hw->device_id == I40E_DEV_ID_25G_SFP28 || + hw->device_id == I40E_DEV_ID_25G_B) { + if (speed_fec_capa) { + speed_fec_capa[num].speed = RTE_ETH_SPEED_NUM_25G; + speed_fec_capa[num].capa = RTE_ETH_FEC_MODE_CAPA_MASK(NOFEC) | + RTE_ETH_FEC_MODE_CAPA_MASK(BASER) | + RTE_ETH_FEC_MODE_CAPA_MASK(AUTO) | + RTE_ETH_FEC_MODE_CAPA_MASK(RS); + } + num++; + } + + if (hw->device_id == I40E_DEV_ID_KX_X722) { + if (speed_fec_capa) { + speed_fec_capa[num].speed = RTE_ETH_SPEED_NUM_25G; + speed_fec_capa[num].capa = RTE_ETH_FEC_MODE_CAPA_MASK(AUTO) | + RTE_ETH_FEC_MODE_CAPA_MASK(RS); + } + num++; + } + + return num; +} + +static int +i40e_fec_get(struct rte_eth_dev *dev, uint32_t *fec_capa) +{ + struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private); + struct i40e_aq_get_phy_abilities_resp abilities; + u32 temp_fec_capa = 0; + u8 fec_cfg; + int ret = 0; + + /* Get the current phy config */ + memset(&abilities, 0, sizeof(abilities)); + ret = i40e_aq_get_phy_capabilities(hw, false, false, &abilities, + NULL); + if (ret) { + PMD_DRV_LOG(ERR, "Failed to get PHY capabilities: %d\n", + ret); + return -ENOTSUP; + } + + fec_cfg = abilities.fec_cfg_curr_mod_ext_info; + if (fec_cfg & I40E_AQ_SET_FEC_AUTO) + temp_fec_capa = RTE_ETH_FEC_MODE_CAPA_MASK(AUTO); + + if (fec_cfg & I40E_AQ_SET_FEC_REQUEST_KR || + fec_cfg & I40E_AQ_SET_FEC_ABILITY_KR) + temp_fec_capa = RTE_ETH_FEC_MODE_CAPA_MASK(BASER); + + if (fec_cfg & I40E_AQ_SET_FEC_REQUEST_RS || + fec_cfg & I40E_AQ_SET_FEC_ABILITY_RS) + temp_fec_capa = RTE_ETH_FEC_MODE_CAPA_MASK(RS); + + if (fec_cfg == 0) + temp_fec_capa = RTE_ETH_FEC_MODE_CAPA_MASK(NOFEC); + + *fec_capa = temp_fec_capa; + + return 0; +} + +static int +i40e_fec_set(struct rte_eth_dev *dev, uint32_t fec_capa) +{ + struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private); + struct i40e_aq_get_phy_abilities_resp abilities; + struct i40e_aq_set_phy_config config = { 0 }; + enum i40e_status_code status; + u8 req_fec; + int ret = 0; + + if (hw->device_id != I40E_DEV_ID_25G_SFP28 && + hw->device_id != I40E_DEV_ID_25G_B && + hw->device_id != I40E_DEV_ID_KX_X722) { + ret = -ENOTSUP; + goto done; + } + + if (hw->mac.type == I40E_MAC_X722 && + !(hw->flags & I40E_HW_FLAG_X722_FEC_REQUEST_CAPABLE)) { + PMD_DRV_LOG(ERR, "Setting FEC encoding not supported by" + " firmware. Please update the NVM image.\n"); + return -ENOTSUP; + } + + /* Copy the current user PHY configuration. The current user PHY + * configuration is initialized during probe from PHY capabilities + * software mode, and updated on set PHY configuration. + */ + switch (fec_capa) { + case RTE_ETH_FEC_MODE_CAPA_MASK(NOFEC): + req_fec = 0; + break; + case RTE_ETH_FEC_MODE_CAPA_MASK(AUTO): + if (hw->mac.type == I40E_MAC_X722) { + PMD_DRV_LOG(ERR, "X722 Unsupported FEC mode: AUTO"); + ret = -EINVAL; + goto done; + } else { + req_fec = I40E_AQ_SET_FEC_AUTO; + } + break; + case RTE_ETH_FEC_MODE_CAPA_MASK(BASER): + req_fec = (I40E_AQ_SET_FEC_REQUEST_KR | + I40E_AQ_SET_FEC_ABILITY_KR); + break; + case RTE_ETH_FEC_MODE_CAPA_MASK(RS): + if (hw->mac.type == I40E_MAC_X722) { + PMD_DRV_LOG(ERR, "X722 Unsupported FEC mode: RS"); + ret = -EINVAL; + goto done; + } else { + req_fec = (I40E_AQ_SET_FEC_REQUEST_RS | + I40E_AQ_SET_FEC_ABILITY_RS); + } + break; + default: + PMD_DRV_LOG(ERR, "Unsupported FEC mode: %d\n", fec_capa); + return -EINVAL; + } + + /* Get the current phy config */ + status = i40e_aq_get_phy_capabilities(hw, false, false, &abilities, + NULL); + if (status) { + PMD_DRV_LOG(ERR, "Failed to get PHY capabilities: %d\n", + status); + ret = -ENOTSUP; + goto done; + } + + if (abilities.fec_cfg_curr_mod_ext_info != req_fec) { + config.phy_type = abilities.phy_type; + config.abilities = abilities.abilities | + I40E_AQ_PHY_ENABLE_ATOMIC_LINK; + config.phy_type_ext = abilities.phy_type_ext; + config.link_speed = abilities.link_speed; + config.eee_capability = abilities.eee_capability; + config.eeer = abilities.eeer_val; + config.low_power_ctrl = abilities.d3_lpan; + config.fec_config = req_fec & I40E_AQ_PHY_FEC_CONFIG_MASK; + status = i40e_aq_set_phy_config(hw, &config, NULL); + if (status) { + PMD_DRV_LOG(ERR, "Failed to set PHY capabilities: %d\n", + status); + ret = -ENOTSUP; + goto done; + } + } + + status = i40e_update_link_info(hw); + if (status) + PMD_DRV_LOG(ERR, "Failed to set PHY capabilities: %d\n", + status); + +done: + return ret; +} + RTE_LOG_REGISTER_SUFFIX(i40e_logtype_init, init, NOTICE); RTE_LOG_REGISTER_SUFFIX(i40e_logtype_driver, driver, NOTICE); #ifdef RTE_ETHDEV_DEBUG_RX