From patchwork Mon Dec 11 04:22:44 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Qiming Yang X-Patchwork-Id: 135002 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 B5BD3436C3; Mon, 11 Dec 2023 05:44:18 +0100 (CET) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 4168C402DC; Mon, 11 Dec 2023 05:44:18 +0100 (CET) Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.10]) by mails.dpdk.org (Postfix) with ESMTP id 582BC402B2 for ; Mon, 11 Dec 2023 05:44:16 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1702269857; x=1733805857; h=from:to:cc:subject:date:message-id:mime-version: content-transfer-encoding; bh=RFMeXNVrll4P7Zv9ysY9IppVT9bOtBte0ABBijy1jRE=; b=V0y5Doq1thYDblNmJ2lZ54MX/HEhQMM7LucpssJQgflM5O1n6w8Bbskt yi4FuUZnKWrUsxrcQYPYae3DLSzT6cBYPePX1Bxy2BDDStChtrnUL/Kof VcNqE6X1MRMIRKeGa1gcZsXdDeH2+tkpisoT9se88E9+kvO+WPnNnof4k oaoUS9C5LnnktRJAWsIFbRZ3lyeIgfTocXQ14JYmC7FYHIGbxJumtXSbE +7CbztRAnu8g+lyj4p5FpQXAjJ6fNbkNd/YUkvnuAjzHoNUZnEeRI44my q7v3dGVl9J6LIV9sOzcawTObizMj1qYecUgRdec7ydsDqjau/dPENMj4f w==; X-IronPort-AV: E=McAfee;i="6600,9927,10920"; a="1719747" X-IronPort-AV: E=Sophos;i="6.04,267,1695711600"; d="scan'208";a="1719747" Received: from orsmga003.jf.intel.com ([10.7.209.27]) by fmvoesa104.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 10 Dec 2023 20:44:15 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10920"; a="722622046" X-IronPort-AV: E=Sophos;i="6.04,267,1695711600"; d="scan'208";a="722622046" Received: from dpdk-qiming3.sh.intel.com ([10.67.110.238]) by orsmga003.jf.intel.com with ESMTP; 10 Dec 2023 20:44:13 -0800 From: Qiming Yang To: dev@dpdk.org Cc: qi.z.zhang@intel.com, Qiming Yang Subject: [PATCH] net/ice: support FEC feature Date: Mon, 11 Dec 2023 04:22:44 +0000 Message-Id: <20231211042244.125196-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 enable three FEC related ops in ice driver. As no speed information can get from HW, this patch only show FEC capability. Signed-off-by: Qiming Yang --- drivers/net/ice/ice_ethdev.c | 175 +++++++++++++++++++++++++++++++++++ 1 file changed, 175 insertions(+) diff --git a/drivers/net/ice/ice_ethdev.c b/drivers/net/ice/ice_ethdev.c index 3ccba4db80..9ef4538626 100644 --- a/drivers/net/ice/ice_ethdev.c +++ b/drivers/net/ice/ice_ethdev.c @@ -178,6 +178,12 @@ static int ice_timesync_read_time(struct rte_eth_dev *dev, static int ice_timesync_write_time(struct rte_eth_dev *dev, const struct timespec *timestamp); static int ice_timesync_disable(struct rte_eth_dev *dev); +static int ice_fec_get_capability(struct rte_eth_dev *dev, struct rte_eth_fec_capa *speed_fec_capa, + unsigned int num); +static int ice_fec_get(struct rte_eth_dev *dev, uint32_t *fec_capa); +static int ice_fec_set(struct rte_eth_dev *dev, uint32_t fec_capa); + + static const uint32_t *ice_buffer_split_supported_hdr_ptypes_get(struct rte_eth_dev *dev); static const struct rte_pci_id pci_id_ice_map[] = { @@ -294,6 +300,9 @@ static const struct eth_dev_ops ice_eth_dev_ops = { .timesync_write_time = ice_timesync_write_time, .timesync_disable = ice_timesync_disable, .tm_ops_get = ice_tm_ops_get, + .fec_get_capability = ice_fec_get_capability, + .fec_get = ice_fec_get, + .fec_set = ice_fec_set, .buffer_split_supported_hdr_ptypes_get = ice_buffer_split_supported_hdr_ptypes_get, }; @@ -6513,6 +6522,172 @@ ice_buffer_split_supported_hdr_ptypes_get(struct rte_eth_dev *dev __rte_unused) return ptypes; } +static int +ice_fec_get_capa_num(struct ice_aqc_get_phy_caps_data *pcaps, struct rte_eth_fec_capa *speed_fec_capa) +{ + int num = 0; + + if (pcaps->caps & ICE_AQC_PHY_EN_AUTO_FEC) { + if (speed_fec_capa) + speed_fec_capa[num].capa = RTE_ETH_FEC_MODE_CAPA_MASK(AUTO); + num++; + } + + if (pcaps->link_fec_options & ICE_AQC_PHY_FEC_10G_KR_40G_KR4_EN || + pcaps->link_fec_options & ICE_AQC_PHY_FEC_10G_KR_40G_KR4_REQ || + pcaps->link_fec_options & ICE_AQC_PHY_FEC_25G_KR_CLAUSE74_EN || + pcaps->link_fec_options & ICE_AQC_PHY_FEC_25G_KR_REQ) { + if (speed_fec_capa) + speed_fec_capa[num].capa = RTE_ETH_FEC_MODE_CAPA_MASK(BASER); + num++; + } + + if (pcaps->link_fec_options & ICE_AQC_PHY_FEC_25G_RS_528_REQ || + pcaps->link_fec_options & ICE_AQC_PHY_FEC_25G_RS_544_REQ || + pcaps->link_fec_options & ICE_AQC_PHY_FEC_25G_RS_CLAUSE91_EN) { + if (speed_fec_capa) + speed_fec_capa[num].capa = RTE_ETH_FEC_MODE_CAPA_MASK(RS); + num++; + } + + if (pcaps->link_fec_options == 0) { + if (speed_fec_capa) + speed_fec_capa[num].capa = RTE_ETH_FEC_MODE_CAPA_MASK(NOFEC); + num++; + } + + return num; +} + +static int +ice_fec_get_capability(struct rte_eth_dev *dev, struct rte_eth_fec_capa *speed_fec_capa, + unsigned int num) +{ + struct ice_hw *hw = ICE_DEV_PRIVATE_TO_HW(dev->data->dev_private); + struct ice_aqc_get_phy_caps_data *pcaps; + unsigned int capa_num; + int ret = 0; + + pcaps = (struct ice_aqc_get_phy_caps_data *) + ice_malloc(hw, sizeof(*pcaps)); + if (!pcaps) + return ICE_ERR_NO_MEMORY; + + ret = ice_aq_get_phy_caps(hw->port_info, false, ICE_AQC_REPORT_TOPO_CAP_MEDIA, + pcaps, NULL); + + printf("cap support: %d\n", pcaps->link_fec_options); + if (ret) + goto done; + + /* first time to get capa_num */ + capa_num = ice_fec_get_capa_num(pcaps, NULL); + if (!speed_fec_capa || num < capa_num) { + ret = capa_num; + goto done; + } + + ret = ice_fec_get_capa_num(pcaps, speed_fec_capa); + if (ret) + goto done; + +done: + ice_free(hw, pcaps); + return ret; +} +static int +ice_fec_get(struct rte_eth_dev *dev, uint32_t *fec_capa) +{ + struct ice_hw *hw = ICE_DEV_PRIVATE_TO_HW(dev->data->dev_private); + struct ice_port_info *pi = hw->port_info; + u32 temp_fec_capa = 0; + int ret = 0; + + if (!pi) + return -ENOTSUP; + + /* Get current FEC mode from port info */ + switch (pi->phy.curr_user_fec_req) { + case ICE_FEC_NONE: + temp_fec_capa = RTE_ETH_FEC_MODE_CAPA_MASK(NOFEC); + break; + case ICE_FEC_AUTO: + case ICE_FEC_DIS_AUTO: + temp_fec_capa = RTE_ETH_FEC_MODE_CAPA_MASK(AUTO); + break; + case ICE_FEC_BASER: + temp_fec_capa = RTE_ETH_FEC_MODE_CAPA_MASK(BASER); + break; + case ICE_FEC_RS: + temp_fec_capa = RTE_ETH_FEC_MODE_CAPA_MASK(RS); + break; + default: + ret = -ENOTSUP; + break; + } + *fec_capa = temp_fec_capa; + return ret; +} + +static int +ice_fec_set(struct rte_eth_dev *dev, uint32_t fec_capa) +{ + struct ice_hw *hw = ICE_DEV_PRIVATE_TO_HW(dev->data->dev_private); + struct ice_port_info *pi = hw->port_info; + struct ice_aqc_set_phy_cfg_data config = { 0 }; + enum ice_fec_mode req_fec; + int ret = 0; + + if (!pi) + 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. + */ + memcpy(&config, &pi->phy.curr_user_phy_cfg, sizeof(config)); + + switch (fec_capa) { + case RTE_ETH_FEC_MODE_CAPA_MASK(NOFEC): + req_fec = ICE_FEC_NONE; + break; + case RTE_ETH_FEC_MODE_CAPA_MASK(AUTO): + if (ice_fw_supports_fec_dis_auto(hw)) + req_fec = ICE_FEC_DIS_AUTO; + else + req_fec = ICE_FEC_AUTO; + break; + case RTE_ETH_FEC_MODE_CAPA_MASK(BASER): + req_fec = ICE_FEC_BASER; + break; + case RTE_ETH_FEC_MODE_CAPA_MASK(RS): + req_fec = ICE_FEC_RS; + break; + default: + PMD_DRV_LOG(ERR, "Unsupported FEC mode: %d\n", fec_capa); + return -EINVAL; + } + + ret = ice_cfg_phy_fec(pi, &config, req_fec); + if (ret) { + PMD_DRV_LOG(ERR, "Failed to set FEC mode"); + return -EINVAL; + } + + config.caps |= ICE_AQ_PHY_ENA_AUTO_LINK_UPDT; + + if (ice_aq_set_phy_cfg(pi->hw, pi, &config, NULL)) + return -EAGAIN; + + /* Save requested FEC config */ + pi->phy.curr_user_fec_req = req_fec; + printf("set current mode: %d\n", pi->phy.curr_user_fec_req); + + return 0; +} + + + static int ice_pci_probe(struct rte_pci_driver *pci_drv __rte_unused, struct rte_pci_device *pci_dev)