From: Qiming Yang <qiming.yang@intel.com>
To: dev@dpdk.org
Cc: qi.z.zhang@intel.com, Qiming Yang <qiming.yang@intel.com>
Subject: [PATCH] net/ice: support FEC feature
Date: Mon, 11 Dec 2023 04:22:44 +0000 [thread overview]
Message-ID: <20231211042244.125196-1-qiming.yang@intel.com> (raw)
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 <qiming.yang@intel.com>
---
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)
--
2.25.1
next reply other threads:[~2023-12-11 4:44 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-12-11 4:22 Qiming Yang [this message]
2024-01-02 4:33 ` Zhang, Qi Z
2024-04-11 9:45 Mingjin Ye
2024-06-27 17:07 ` Medvedkin, Vladimir
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20231211042244.125196-1-qiming.yang@intel.com \
--to=qiming.yang@intel.com \
--cc=dev@dpdk.org \
--cc=qi.z.zhang@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).